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
}
}