.NET 6 基于IDistributedCache实现Redis与MemoryCache的缓存帮助类 ...

打印 上一主题 下一主题

主题 868|帖子 868|积分 2604

本文通过IDistributedCache的接口方法,实现RedisMemoryCache统一帮助类。只需要在配置文件中简单的配置一下,就可以实现Redis与MemoryCache的切换。

目录

IDistributedCache

IDistributedCache 方法:

方法说明Get(String)获取具有给定键的值。GetAsync(String, CancellationToken)获取具有给定键的值。Refresh(String)基于缓存中某个值的键刷新该值,并重置其可调到期超时(如果有)。RefreshAsync(String, CancellationToken)基于缓存中某个值的键刷新该值,并重置其可调到期超时(如果有)。Remove(String)删除具有给定键的值。RemoveAsync(String, CancellationToken)删除具有给定键的值。Set(String, Byte[], DistributedCacheEntryOptions)设置具有给定键的值。SetAsync(String, Byte[], DistributedCacheEntryOptions, CancellationToken)设置具有给定键的值。IDistributedCache 还提供了一些扩展方法,本文的帮助类就是通过扩展方法完成的。
IDistributedCache 扩展方法:

方法说明GetString(IDistributedCache, String)使用指定的键从指定的缓存中获取字符串。GetStringAsync(IDistributedCache, String, CancellationToken)使用指定的键从指定的缓存异步获取字符串。Set(IDistributedCache, String, Byte[])使用指定的键设置指定缓存中的字节序列。SetAsync(IDistributedCache, String, Byte[], CancellationToken)使用指定的键异步设置指定缓存中的字节序列。SetString(IDistributedCache, String, String)使用指定的键在指定的缓存中设置字符串。SetString(IDistributedCache, String, String, DistributedCacheEntryOptions)使用指定的键在指定的缓存中设置字符串。SetStringAsync(IDistributedCache, String, String, DistributedCacheEntryOptions, CancellationToken)使用指定的键在指定的缓存中异步设置字符串。SetStringAsync(IDistributedCache, String, String, CancellationToken)使用指定的键在指定的缓存中异步设置字符串。ICache 接口

ICache接口提供了设置缓存、获取缓存、删除缓存和刷新缓存的接口方法。
  1. namespace CacheHelper
  2. {
  3.     public interface ICache
  4.     {
  5.         #region 设置缓存
  6.         /// <summary>
  7.         /// 设置缓存
  8.         /// </summary>
  9.         /// <param name="key">缓存Key</param>
  10.         /// <param name="value">值</param>
  11.         void SetCache(string key, object value);
  12.         /// <summary>
  13.         /// 设置缓存
  14.         /// </summary>
  15.         /// <param name="key">缓存Key</param>
  16.         /// <param name="value">值</param>
  17.         Task SetCacheAsync(string key, object value);
  18.         /// <summary>
  19.         /// 设置缓存
  20.         /// 注:默认过期类型为绝对过期
  21.         /// </summary>
  22.         /// <param name="key">缓存Key</param>
  23.         /// <param name="value">值</param>
  24.         /// <param name="timeout">过期时间间隔</param>
  25.         void SetCache(string key, object value, TimeSpan timeout);
  26.         /// <summary>
  27.         /// 设置缓存
  28.         /// 注:默认过期类型为绝对过期
  29.         /// </summary>
  30.         /// <param name="key">缓存Key</param>
  31.         /// <param name="value">值</param>
  32.         /// <param name="timeout">过期时间间隔</param>
  33.         Task SetCacheAsync(string key, object value, TimeSpan timeout);
  34.         /// <summary>
  35.         /// 设置缓存
  36.         /// 注:默认过期类型为绝对过期
  37.         /// </summary>
  38.         /// <param name="key">缓存Key</param>
  39.         /// <param name="value">值</param>
  40.         /// <param name="timeout">过期时间间隔</param>
  41.         /// <param name="expireType">过期类型</param>  
  42.         void SetCache(string key, object value, TimeSpan timeout, ExpireType expireType);
  43.         /// <summary>
  44.         /// 设置缓存
  45.         /// 注:默认过期类型为绝对过期
  46.         /// </summary>
  47.         /// <param name="key">缓存Key</param>
  48.         /// <param name="value">值</param>
  49.         /// <param name="timeout">过期时间间隔</param>
  50.         /// <param name="expireType">过期类型</param>  
  51.         Task SetCacheAsync(string key, object value, TimeSpan timeout, ExpireType expireType);
  52.         #endregion
  53.         #region 获取缓存
  54.         /// <summary>
  55.         /// 获取缓存
  56.         /// </summary>
  57.         /// <param name="key">缓存Key</param>
  58.         string GetCache(string key);
  59.         /// <summary>
  60.         /// 获取缓存
  61.         /// </summary>
  62.         /// <param name="key">缓存Key</param>
  63.         Task<string> GetCacheAsync(string key);
  64.         /// <summary>
  65.         /// 获取缓存
  66.         /// </summary>
  67.         /// <param name="key">缓存Key</param>
  68.         T GetCache<T>(string key);
  69.         /// <summary>
  70.         /// 获取缓存
  71.         /// </summary>
  72.         /// <param name="key">缓存Key</param>
  73.         Task<T> GetCacheAsync<T>(string key);
  74.         #endregion
  75.         #region 删除缓存
  76.         /// <summary>
  77.         /// 清除缓存
  78.         /// </summary>
  79.         /// <param name="key">缓存Key</param>
  80.         void RemoveCache(string key);
  81.         /// <summary>
  82.         /// 清除缓存
  83.         /// </summary>
  84.         /// <param name="key">缓存Key</param>
  85.         Task RemoveCacheAsync(string key);
  86.         #endregion
  87.         #region 刷新缓存
  88.         /// <summary>
  89.         /// 刷新缓存
  90.         /// </summary>
  91.         /// <param name="key">缓存Key</param>
  92.         void RefreshCache(string key);
  93.         /// <summary>
  94.         /// 刷新缓存
  95.         /// </summary>
  96.         /// <param name="key">缓存Key</param>
  97.         Task RefreshCacheAsync(string key);
  98.         #endregion
  99.     }
  100. }
复制代码
ExpireType枚举

ExpireType枚举标识缓存的过期类型,分为绝对过期与相对过期两个类型。
绝对过期:即自创建一段时间后就过期
相对过期:即该键未被访问后一段时间后过期,若此键一直被访问则过期时间自动延长。
  1. namespace CacheHelper
  2. {
  3.     public enum ExpireType
  4.     {
  5.         /// <summary>
  6.         /// 绝对过期
  7.         /// 注:即自创建一段时间后就过期
  8.         /// </summary>
  9.         Absolute,
  10.         /// <summary>
  11.         /// 相对过期
  12.         /// 注:即该键未被访问后一段时间后过期,若此键一直被访问则过期时间自动延长
  13.         /// </summary>
  14.         Relative,
  15.     }
  16. }
复制代码
CacheType 枚举

是使用MemoryCache,还是Redis,MemoryCache不支持分布式,Redis支持分布式。
  1. namespace CacheHelper
  2. {
  3.     public enum CacheType
  4.     {
  5.         /// <summary>
  6.         /// 使用内存缓存(不支持分布式)
  7.         /// </summary>
  8.         Memory,
  9.         /// <summary>
  10.         /// 使用Redis缓存(支持分布式)
  11.         /// </summary>
  12.         Redis
  13.     }
  14. }
复制代码
CacheHelper 缓存帮助类
  1. namespace CacheHelper
  2. {
  3.     public class CacheHelper : ICache
  4.     {
  5.         readonly IDistributedCache _cache;
  6.         public CacheHelper(IDistributedCache cache)
  7.         {
  8.             _cache = cache;
  9.         }
  10.         protected string BuildKey(string idKey)
  11.         {
  12.             return $"Cache_{GetType().FullName}_{idKey}";
  13.         }
  14.         public void SetCache(string key, object value)
  15.         {
  16.             string cacheKey = BuildKey(key);
  17.             _cache.SetString(cacheKey, value.ToJson());
  18.         }
  19.         public async Task SetCacheAsync(string key, object value)
  20.         {
  21.             string cacheKey = BuildKey(key);
  22.             await _cache.SetStringAsync(cacheKey, value.ToJson());
  23.         }
  24.         public void SetCache(string key, object value, TimeSpan timeout)
  25.         {
  26.             string cacheKey = BuildKey(key);
  27.             _cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
  28.             {
  29.                 AbsoluteExpiration = new DateTimeOffset(DateTime.Now + timeout)
  30.             });
  31.         }
  32.         public async Task SetCacheAsync(string key, object value, TimeSpan timeout)
  33.         {
  34.             string cacheKey = BuildKey(key);
  35.             await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
  36.             {
  37.                 AbsoluteExpiration = new DateTimeOffset(DateTime.Now + timeout)
  38.             });
  39.         }
  40.         public void SetCache(string key, object value, TimeSpan timeout, ExpireType expireType)
  41.         {
  42.             string cacheKey = BuildKey(key);
  43.             if (expireType == ExpireType.Absolute)
  44.             {
  45.                 //这里没转换标准时间,Linux时区会有问题?
  46.                 _cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
  47.                 {
  48.                     AbsoluteExpiration = new DateTimeOffset(DateTime.Now + timeout)
  49.                 });
  50.             }
  51.             else
  52.             {
  53.                 _cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
  54.                 {
  55.                     AbsoluteExpirationRelativeToNow = timeout
  56.                 });
  57.             }
  58.         }
  59.         public async Task SetCacheAsync(string key, object value, TimeSpan timeout, ExpireType expireType)
  60.         {
  61.             string cacheKey = BuildKey(key);
  62.             if (expireType == ExpireType.Absolute)
  63.             {
  64.                 //这里没转换标准时间,Linux时区会有问题?
  65.                 await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
  66.                 {
  67.                     AbsoluteExpiration = new DateTimeOffset(DateTime.Now + timeout)
  68.                 });
  69.             }
  70.             else
  71.             {
  72.                 await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
  73.                 {
  74.                     AbsoluteExpirationRelativeToNow = timeout
  75.                 });
  76.             }
  77.         }
  78.         public string GetCache(string idKey)
  79.         {
  80.             if (idKey.IsNullOrEmpty())
  81.             {
  82.                 return null;
  83.             }
  84.             string cacheKey = BuildKey(idKey);
  85.             var cache = _cache.GetString(cacheKey);
  86.             return cache;
  87.         }
  88.         public async Task<string> GetCacheAsync(string key)
  89.         {
  90.             if (key.IsNullOrEmpty())
  91.             {
  92.                 return null;
  93.             }
  94.             string cacheKey = BuildKey(key);
  95.             var cache = await _cache.GetStringAsync(cacheKey);
  96.             return cache;
  97.         }
  98.         public T GetCache<T>(string key)
  99.         {
  100.             var cache = GetCache(key);
  101.             if (!cache.IsNullOrEmpty())
  102.             {
  103.                 return cache.ToObject<T>();
  104.             }
  105.             return default(T);
  106.         }
  107.         public async Task<T> GetCacheAsync<T>(string key)
  108.         {
  109.             var cache = await GetCacheAsync(key);
  110.             if (!string.IsNullOrEmpty(cache))
  111.             {
  112.                 return cache.ToObject<T>();
  113.             }
  114.             return default(T);
  115.         }
  116.         public void RemoveCache(string key)
  117.         {
  118.             _cache.Remove(BuildKey(key));
  119.         }
  120.         public async Task RemoveCacheAsync(string key)
  121.         {
  122.             await _cache.RemoveAsync(BuildKey(key));
  123.         }
  124.         public void RefreshCache(string key)
  125.         {
  126.             _cache.Refresh(BuildKey(key));
  127.         }
  128.         public async Task RefreshCacheAsync(string key)
  129.         {
  130.             await _cache.RefreshAsync(BuildKey(key));
  131.         }
  132.     }
  133. }
复制代码
CacheHelper 中,自定义了一个string的扩展方法ToObject()。ToObject()扩展方法使用了 Newtonsoft.Json。
  1. /// <summary>
  2. /// 将Json字符串反序列化为对象
  3. /// </summary>
  4. /// <typeparam name="T">对象类型</typeparam>
  5. /// <param name="jsonStr">Json字符串</param>
  6. /// <returns></returns>
  7. public static T ToObject<T>(this string jsonStr)
  8. {
  9.     return JsonConvert.DeserializeObject<T>(jsonStr);
  10. }
复制代码
CacheHelper 的使用方法

安装Redis依赖

Redis依赖我使用的是Caching.CSRedis,安装依赖:
  1. PM> Install-Package Caching.CSRedis -Version 3.6.90
复制代码
配置appsettings.json

在appsettings.json中,对缓存进行配置:
  1. "Cache": {
  2.     "CacheType": "Memory", // "Memory OR Redis"
  3.     "RedisEndpoint": "127.0.0.1:6379" //Redis节点地址,定义详见 https://github.com/2881099/csredis
  4.   },
复制代码
如果要使用MemoryCache,CacheType就设置为Memory,如果要使用Redis,CacheType就设置为Redis。如果设置为Redis的话,还需要配置RedisEndpoint,保证Redis节点可用。
CacheOptions配置

编写一个名为CacheOptions的类。用于获取配置文件的配置节内容
  1. namespace CacheHelper
  2. {
  3.     public class CacheOptions
  4.     {
  5.         public CacheType CacheType { get; set; }
  6.         public string RedisEndpoint { get; set; }
  7.     }
  8. }
复制代码
IHostBuilder扩展方法UseCache

编写一个IHostBuilder的扩展方法UseCache,用于注入MemoryCache或是Redis
  1. public static IHostBuilder UseCache(this IHostBuilder hostBuilder)
  2. {
  3.     hostBuilder.ConfigureServices((buidlerContext, services) =>
  4.     {
  5.         var cacheOption = buidlerContext.Configuration.GetSection("Cache").Get<CacheOptions>();
  6.         switch (cacheOption.CacheType)
  7.         {
  8.             case CacheType.Memory: services.AddDistributedMemoryCache(); break;
  9.             case CacheType.Redis:
  10.                 {
  11.                     var csredis = new CSRedisClient(cacheOption.RedisEndpoint);
  12.                     RedisHelper.Initialization(csredis);
  13.                     services.AddSingleton(csredis);
  14.                     services.AddSingleton<IDistributedCache>(new CSRedisCache(RedisHelper.Instance));
  15.                 }; break;
  16.             default: throw new Exception("缓存类型无效");
  17.         }
  18.     });
  19.     return hostBuilder;
  20. }
复制代码
Program.cs中引用
  1. var builder = WebApplication.CreateBuilder(args);
  2. builder.Host.UseCache();
复制代码
CacheHelper的使用。
  1. public class HomeController
  2. {
  3.         readonly ICache _cache;
  4.         public HomeController
  5.         (
  6.                 ICache cache,
  7.         )
  8.         {
  9.                 _cache = cache;
  10.         }
  11.        
  12.         public async Task CacheTest(string key)
  13.         {
  14.                 string cache_value = "hello cache";
  15.                 //同步方法
  16.                 _cache.SetCache(key,cache_value );
  17.                 string v = _cache.GetCache<string>(key);
  18.                 _cache.RemoveCache(key);
  19.                 //异步方法
  20.                 await _cache.SetCacheAsync(key,cache_value );
  21.                 string val = await _cache.GetCacheAsync<string>(key);
  22.                 await _cache.RemoveCacheAsync(key);
  23.         }
  24. }
复制代码
总结

暂无,下次再会!
欢迎大家关注我的微信公众号,一起进步,一起成长
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

千千梦丶琪

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表