.Net Core 缓存方式(二)自定义分布式缓存的扩展方法(5)
.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);