上一篇讲解了Redis的搭建及ServiceStack.Redis 与 StackExchange.Reids 的区别https://blog.csdn.net/qq_39569480/article/details/105249607
这篇文章遗我们来说下使用Microsoft.Extensions.Caching.StackExchangeRedis来对redis进行操作及帮助类。
首先在windows上安装redis 在上边连接中有教程 .
创建webapi项目
在包管理器中安装Microsoft.Extensions.Caching.StackExchangeRedis
在appsettings.json中添加连接字符串:(redis连接字符串)
"ConnectionStrings": {"Redis": "123.123.33.22:6379,password=123456!,ConnectTimeout=15000,SyncTimeout=5000"},
定义一个接口
public interface ICache
{#region 设置缓存 /// <summary>/// 设置缓存/// </summary>/// <param name="key">缓存Key</param>/// <param name="value">值</param>void SetCache(string key, object value);/// <summary>/// 设置缓存/// </summary>/// <param name="key">缓存Key</param>/// <param name="value">值</param>Task SetCacheAsync(string key, object value);/// <summary>/// 设置缓存/// 注:默认过期类型为绝对过期/// </summary>/// <param name="key">缓存Key</param>/// <param name="value">值</param>/// <param name="minutes">过期时间间隔 以分钟为单位</param>void SetCache(string key, object value,int minutes);/// <summary>/// 设置缓存/// 注:默认过期类型为绝对过期/// </summary>/// <param name="key">缓存Key</param>/// <param name="value">值</param>/// <param name="timeout">过期时间间隔 以分钟为单位</param>Task SetCacheAsync(string key, object value, int minutes);/// <summary>/// 设置缓存/// 注:默认过期类型为绝对过期/// </summary>/// <param name="key">缓存Key</param>/// <param name="value">值</param>/// <param name="minutes">过期时间间隔 以分钟为单位</param>/// <param name="expireType">过期类型</param> void SetCache(string key, object value, int minutes, ExpireType expireType);/// <summary>/// 设置缓存/// 注:默认过期类型为绝对过期/// </summary>/// <param name="key">缓存Key</param>/// <param name="value">值</param>/// <param name="minutes">过期时间间隔 以分钟为单位</param>/// <param name="expireType">过期类型</param> Task SetCacheAsync(string key, object value, int minutes, ExpireType expireType);#endregion#region 获取缓存/// <summary>/// 获取缓存/// </summary>/// <param name="key">缓存Key</param>string GetCache(string key);/// <summary>/// 获取缓存/// </summary>/// <param name="key">缓存Key</param>Task<string> GetCacheAsync(string key);/// <summary>/// 获取缓存,没有则添加/// </summary>/// <param name="key"></param>/// <param name="value"></param>/// <param name="minutes"></param>/// <param name="expireType">过期类型,默认绝对过期</param>/// <returns></returns>Task<string> GetOrAddAsync(string key, object value, int minutes, ExpireType expireType = 0);/// <summary>/// 获取缓存/// </summary>/// <param name="key">缓存Key</param>T GetCache<T>(string key);/// <summary>/// 获取缓存/// </summary>/// <param name="key">缓存Key</param>Task<T> GetCacheAsync<T>(string key);/// <summary>/// 获取泛型缓存,没有则添加/// </summary>/// <typeparam name="T"></typeparam>/// <param name="key"></param>/// <param name="value"></param>/// <param name="minutes"></param>/// <param name="expireType">过期类型,默认绝对过期</param>/// <returns></returns>Task<T> GetOrAddAsync<T>(string key, object value, int minutes, ExpireType expireType = 0);#endregion#region 删除缓存/// <summary>/// 清除缓存/// </summary>/// <param name="key">缓存Key</param>void RemoveCache(string key);/// <summary>/// 清除缓存/// </summary>/// <param name="key">缓存Key</param>Task RemoveCacheAsync(string key);#endregion#region 刷新缓存/// <summary>/// 刷新缓存/// </summary>/// <param name="key">缓存Key</param>void RefreshCache(string key);/// <summary>/// 刷新缓存/// </summary>/// <param name="key">缓存Key</param>Task RefreshCacheAsync(string key);#endregion
}
实现接口中定义的方法
public class CacheHelper : ICache
{readonly IDistributedCache _cache;public CacheHelper(IDistributedCache cache){_cache = cache;}protected string BuildKey(string idKey){return $"Cache_{idKey}";}public void SetCache(string key, object value){string cacheKey = BuildKey(key);_cache.SetString(cacheKey, value.ToJson());}public async Task SetCacheAsync(string key, object value){string cacheKey = BuildKey(key);await _cache.SetStringAsync(cacheKey, value.ToJson());}public void SetCache(string key, object value,int minutes){string cacheKey = BuildKey(key);_cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)});}public async Task SetCacheAsync(string key, object value, int minutes){string cacheKey = BuildKey(key);await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)});}public void SetCache(string key, object value, int minutes, ExpireType expireType){string cacheKey = BuildKey(key);if (expireType == ExpireType.Absolute){//这里没转换标准时间,Linux时区会有问题?_cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)});}else{_cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(minutes)});}}public async Task SetCacheAsync(string key, object value, int minutes, ExpireType expireType){string cacheKey = BuildKey(key);if (expireType == ExpireType.Absolute){//这里没转换标准时间,Linux时区会有问题?await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)});}else{await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(minutes)});}}public string GetCache(string idKey){if (idKey.IsNullOrEmpty()){return null;}string cacheKey = BuildKey(idKey);var cache = _cache.GetString(cacheKey);return cache;}public async Task<string> GetCacheAsync(string key){if (key.IsNullOrEmpty()){return null;}string cacheKey = BuildKey(key);var cache = await _cache.GetStringAsync(cacheKey);return cache;}public async Task<string> GetOrAddAsync(string key,object value,int minutes, ExpireType expireType=0){if (key.IsNullOrEmpty()) return null;string cacheKey = BuildKey(key);var cache = await _cache.GetStringAsync(cacheKey);if (cache==null&& value!=null){string json= value.ToJson();if (expireType == ExpireType.Absolute){//这里没转换标准时间,Linux时区会有问题?await _cache.SetStringAsync(cacheKey, json, new DistributedCacheEntryOptions{AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)});}else{await _cache.SetStringAsync(cacheKey, json, new DistributedCacheEntryOptions{AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(minutes)});}return json;}return cache;}public T GetCache<T>(string key){var cache = GetCache(key);if (!cache.IsNullOrEmpty()){return cache.ToObject<T>();}return default(T);}public async Task<T> GetCacheAsync<T>(string key){var cache = await GetCacheAsync(key);if (!string.IsNullOrEmpty(cache)){return cache.ToObject<T>();}return default(T);}public async Task<T> GetOrAddAsync<T>(string key, object value, int minutes, ExpireType expireType = 0){if (key.IsNullOrEmpty()) return default(T);string cacheKey = BuildKey(key);var cache = await _cache.GetStringAsync(cacheKey);if (cache == null && value != null){string json = value.ToJson();if (expireType == ExpireType.Absolute){//这里没转换标准时间,Linux时区会有问题?await _cache.SetStringAsync(cacheKey, json, new DistributedCacheEntryOptions{AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)});}else{await _cache.SetStringAsync(cacheKey, json, new DistributedCacheEntryOptions{AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(minutes)});}return json.ToObject<T>();}return cache.ToObject<T>();}public void RemoveCache(string key){_cache.Remove(BuildKey(key));}public async Task RemoveCacheAsync(string key){await _cache.RemoveAsync(BuildKey(key));}public void RefreshCache(string key){_cache.Refresh(BuildKey(key));}public async Task RefreshCacheAsync(string key){await _cache.RefreshAsync(BuildKey(key));}
}
定义一个枚举的过期类型
public enum ExpireType
{/// <summary>/// 绝对过期/// 注:即自创建一段时间后就过期/// </summary>Absolute,/// <summary>/// 相对过期/// 注:即该键未被访问后一段时间后过期,若此键一直被访问则过期时间自动延长/// </summary>Relative,
}
定义一个string的扩展方法
public static class ValueToObject
{/// <summary>/// 将Json字符串反序列化为对象/// </summary>/// <typeparam name="T">对象类型</typeparam>/// <param name="jsonStr">Json字符串</param>/// <returns></returns>public static T ToObject<T>(this string jsonStr){return JsonConvert.DeserializeObject<T>(jsonStr);}/// <summary>/// 将字符串序列化为json/// </summary>/// <param name="str"></param>/// <returns></returns>public static string ToJson(this object str){return JsonConvert.SerializeObject(str);}
}
在Program.cs文件中注入并添加redis
builder.Services.AddScoped(typeof(ICache), typeof(CacheHelper));//注入builder.Services.AddStackExchangeRedisCache(o =>
{//redis连接o.Configuration = builder.Configuration.GetConnectionString("Redis");//设置缓存key的前缀//o.InstanceName = "";
});
控制器中使用
[Route("demo")]
[ApiController]
//[Authorize]
public class DemoController : ControllerBase
{private readonly IDemoService _demo;public DemoController(IDemoService demo){_demo = demo;}/// <summary>/// 获取列表/// </summary>/// <param name="input"></param>/// <returns></returns>[HttpGet]public async Task<dynamic> Get(int id){DemoGetOutPut demo=await _cache.GetOrAddAsync<DemoGetOutPut>($"demo{id}", async () => await GetDemo(id),20);return demo;}public async Task<dynamic> Get(int id){return new { name= "张三", age= 18 };}
}