.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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章