using System; using System.Runtime.Caching; using System.Threading.Tasks; namespace BinaryDad.Extensions { /// /// In-memory cache helper wrapping the /// public static class CacheHelper { private const int DefaultCacheDuration = 10; // minutes #region Add /// /// Adds an item to the cache for a duration (in minutes) /// /// /// /// The length of the cache duration in minutes /// Indicates whether the cache duration is sliding or absolute public static void Add(string key, object value, int cacheDuration = DefaultCacheDuration, bool isSliding = false) => Add(key, value, GetCacheItemPolicy(cacheDuration, isSliding)); /// /// Adds an item to the cache with an absolute expiration /// /// /// /// public static void Add(string key, object value, DateTime absoluteExpiration) => Add(key, value, GetCacheItemPolicy(absoluteExpiration)); #endregion #region Get /// /// Retrieves an object from the cache, and if not found, retrieves and sets from a source delegate /// /// /// /// /// Amount of time in minutes to persist the cache if loaded from source /// Indicates whether the cache duration is sliding or absolute /// public static T Get(string key, Func source, int cacheDuration = DefaultCacheDuration, bool isSliding = false) => Get(key, source, GetCacheItemPolicy(cacheDuration, isSliding)); /// /// Retrieves an object from the cache, and if not found, retrieves and sets from a source delegate /// /// /// /// /// Amount of time in minutes to persist the cache if loaded from source /// Indicates whether the cache duration is sliding or absolute /// public static Task GetAsync(string key, Func> source, int cacheDuration = DefaultCacheDuration, bool isSliding = false) => GetAsync(key, source, GetCacheItemPolicy(cacheDuration, isSliding)); /// /// Retrieves an object from the cache, and if not found, retrieves and sets from a source delegate /// /// /// /// /// The date and time when the cache will invalidate /// public static T Get(string key, Func source, DateTime absoluteExpiration) => Get(key, source, GetCacheItemPolicy(absoluteExpiration)); /// /// Retrieves an object from the cache, and if not found, retrieves and sets from a source delegate /// /// /// /// /// The date and time when the cache will invalidate /// public static Task GetAsync(string key, Func> source, DateTime absoluteExpiration) => GetAsync(key, source, GetCacheItemPolicy(absoluteExpiration)); /// /// Retrieves an object from the cache /// /// /// /// public static T Get(string key) => MemoryCache.Default[key].To(); #endregion /// /// Removes an item from the cache /// /// public static void Remove(string key) => MemoryCache.Default.Remove(key); /// /// Returns true if the value exists in the cache /// /// /// public static bool Exists(string key) => MemoryCache.Default[key] != null; #region Private Methods /// /// Adds an item to the cache with a custom /// /// /// /// private static void Add(string key, object value, CacheItemPolicy cacheItemPolicy) { Remove(key); MemoryCache.Default.Add(key, value, cacheItemPolicy); } /// /// Retrieves an object from the cache, and if not found, retrieves and sets from a source delegate /// /// /// /// /// /// private static T Get(string key, Func source, CacheItemPolicy cacheItemPolicy) { if (Exists(key)) { return Get(key); } // if the value does not exist in the cache, automatically add it and return it var value = source.Invoke(); Add(key, value, cacheItemPolicy); return value; } /// /// Retrieves an object from the cache, and if not found, retrieves and sets from a source delegate /// /// /// /// /// /// private static async Task GetAsync(string key, Func> source, CacheItemPolicy cacheItemPolicy) { if (Exists(key)) { return Get(key); } // if the value does not exist in the cache, automatically add it and return it var value = await source.Invoke(); Add(key, value, cacheItemPolicy); return value; } /// /// Creates a given an absolute expiration date/time /// /// /// private static CacheItemPolicy GetCacheItemPolicy(DateTime absoluteExpiration) { return new CacheItemPolicy { AbsoluteExpiration = absoluteExpiration }; } /// /// Creates a given a cache duration (in minutes) and if the cache expiration is sliding /// /// /// /// private static CacheItemPolicy GetCacheItemPolicy(int cacheDuration, bool isSliding) { if (isSliding) { return new CacheItemPolicy { SlidingExpiration = new TimeSpan(0, cacheDuration, 0) }; } return GetCacheItemPolicy(DateTime.Now.AddMinutes(cacheDuration)); } #endregion } }