.Net Core 緩存方式(二)自定義分佈式緩存的擴展方法(5)
IDistributedCache 的擴展方法
IDistributedCache 的擴展方法實現了類似於 cache.GetString(key); 這種寫法,但是實際使用起來還需要寫多行 類轉字符串的代碼,這時候就可以自己自定義 IDistributedCache 的擴展方法。
實現類似 MemoryCache的GetOrCreate方法
_cache.GetOrCreate
var cacheEntry = _cache.GetOrCreate(CacheKeys.Entry, entry =>
{
entry.SlidingExpiration = TimeSpan.FromSeconds(3);
return DateTime.Now;
});
MemoryCache的GetOrCreate好用,看下實現方法:
public static TItem GetOrCreate<TItem>(this IMemoryCache cache, object key, Func<ICacheEntry, TItem> factory)
{
if (!cache.TryGetValue(key, out object result))
{
ICacheEntry entry = cache.CreateEntry(key);
result = factory(entry);
entry.SetValue(result);
// need to manually call dispose instead of having a using
// in case the factory passed in throws, in which case we
// do not want to add the entry to the cache
entry.Dispose();
}
return (TItem)result;
}
我們可以寫個類似 GetOrCreate 的擴展方法
public static TItem GetOrCreate<TItem>(this IDistributedCache cache, string key, Func<TItem> factory, DistributedCacheEntryOptions options)
{
if (!cache.TryGetValue(key, out TItem obj))
{
obj = factory();
cache.Set(key, obj, options);
}
return (TItem)obj;
}
自定義分佈式緩存的擴展方法
我這裏設置默認 半小時過期
public static class DistributedCacheExtensions
{
private static readonly DistributedCacheEntryOptions DefaultOptions = new DistributedCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(30));
public static TItem Get<TItem>(this IDistributedCache cache, string key)
{
try
{
var valueString = cache.GetString(key);
if (string.IsNullOrEmpty(valueString))
{
return default(TItem);
}
return JsonSerializer.Deserialize<TItem>(valueString);
}
catch (Exception e)
{
return default(TItem);
}
}
public static async Task<TItem> GetAsync<TItem>(this IDistributedCache cache, string key, CancellationToken token = default(CancellationToken))
{
try
{
var valueString = await cache.GetStringAsync(key, token);
if (string.IsNullOrEmpty(valueString))
{
return default(TItem);
}
return JsonSerializer.Deserialize<TItem>(valueString);
}
catch (Exception e)
{
return default(TItem);
}
}
public static bool TryGetValue<TItem>(this IDistributedCache cache, string key, out TItem value)
{
var valueString = cache.GetString(key);
if (!string.IsNullOrEmpty(valueString))
{
value = JsonSerializer.Deserialize<TItem>(valueString);
return true;
}
value = default(TItem);
return false;
}
public static void Set<TItem>(this IDistributedCache cache, string key, TItem value)
{
cache.SetString(key, JsonSerializer.Serialize(value), DefaultOptions);
}
public static void Set<TItem>(this IDistributedCache cache, string key, TItem value, DistributedCacheEntryOptions options)
{
cache.SetString(key, JsonSerializer.Serialize(value), options);
}
public static async Task SetAsync<TItem>(this IDistributedCache cache, string key, TItem value, CancellationToken token = default(CancellationToken))
{
await cache.SetStringAsync(key, JsonSerializer.Serialize(value), DefaultOptions, token);
}
public static async Task SetAsync<TItem>(this IDistributedCache cache, string key, TItem value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken))
{
await cache.SetStringAsync(key, JsonSerializer.Serialize(value), options, token);
}
public static TItem GetOrCreate<TItem>(this IDistributedCache cache, string key, Func<TItem> factory)
{
if (!cache.TryGetValue(key, out TItem obj))
{
obj = factory();
cache.Set(key, obj);
}
return (TItem)obj;
}
public static TItem GetOrCreate<TItem>(this IDistributedCache cache, string key, Func<TItem> factory, DistributedCacheEntryOptions options)
{
if (!cache.TryGetValue(key, out TItem obj))
{
obj = factory();
cache.Set(key, obj, options);
}
return (TItem)obj;
}
public static async Task<TItem> GetOrCreateAsync<TItem>(this IDistributedCache cache, string key, Func<Task<TItem>> factory)
{
if (!cache.TryGetValue(key, out TItem obj))
{
obj = await factory();
await cache.SetAsync(key, obj);
}
return (TItem)obj;
}
public static async Task<TItem> GetOrCreateAsync<TItem>(this IDistributedCache cache, string key, Func<Task<TItem>> factory, DistributedCacheEntryOptions options)
{
if (!cache.TryGetValue(key, out TItem obj))
{
obj = await factory();
await cache.SetAsync(key, obj, options);
}
return (TItem)obj;
}
}
用法 example:
private readonly IDistributedCache _distributedCache;
public CategoryService(
IDistributedCache distributedCache)
{
_distributedCache = distributedCache;
}
public async Task<List<CategoryList>> GetCategoryList()
{
return await _distributedCache.GetOrCreateAsync(ProductCaching.GetCategoryList,
async () => await GetFormHybris());
}
var saveCode = _distributedCache.Get<string>(cacheKey);
var order= _distributedCache.Get<Order>(cacheKey);