.NET 6 基于IDistributedCache实现Redis与MemoryCache的缓存帮助类
admin
2024-03-03 01:31:22
0

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

目录

  • IDistributedCache
    • IDistributedCache 方法:
    • IDistributedCache 扩展方法:
  • ICache 接口
  • ExpireType枚举
  • CacheType 枚举
  • CacheHelper 缓存帮助类
  • CacheHelper 的使用方法
    • 安装Redis依赖
    • 配置appsettings.json
    • CacheOptions配置
    • IHostBuilder扩展方法UseCache
    • Program.cs中引用
  • CacheHelper的使用。
  • 总结

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接口提供了设置缓存、获取缓存、删除缓存和刷新缓存的接口方法。

namespace CacheHelper
{public interface ICache{#region 设置缓存 /// /// 设置缓存/// /// 缓存Key/// 值void SetCache(string key, object value);/// /// 设置缓存/// /// 缓存Key/// 值Task SetCacheAsync(string key, object value);/// /// 设置缓存/// 注:默认过期类型为绝对过期/// /// 缓存Key/// 值/// 过期时间间隔void SetCache(string key, object value, TimeSpan timeout);/// /// 设置缓存/// 注:默认过期类型为绝对过期/// /// 缓存Key/// 值/// 过期时间间隔Task SetCacheAsync(string key, object value, TimeSpan timeout);/// /// 设置缓存/// 注:默认过期类型为绝对过期/// /// 缓存Key/// 值/// 过期时间间隔/// 过期类型  void SetCache(string key, object value, TimeSpan timeout, ExpireType expireType);/// /// 设置缓存/// 注:默认过期类型为绝对过期/// /// 缓存Key/// 值/// 过期时间间隔/// 过期类型  Task SetCacheAsync(string key, object value, TimeSpan timeout, ExpireType expireType);#endregion#region 获取缓存/// /// 获取缓存/// /// 缓存Keystring GetCache(string key);/// /// 获取缓存/// /// 缓存KeyTask GetCacheAsync(string key);/// /// 获取缓存/// /// 缓存KeyT GetCache(string key);/// /// 获取缓存/// /// 缓存KeyTask GetCacheAsync(string key);#endregion#region 删除缓存/// /// 清除缓存/// /// 缓存Keyvoid RemoveCache(string key);/// /// 清除缓存/// /// 缓存KeyTask RemoveCacheAsync(string key);#endregion#region 刷新缓存/// /// 刷新缓存/// /// 缓存Keyvoid RefreshCache(string key);/// /// 刷新缓存/// /// 缓存KeyTask RefreshCacheAsync(string key);#endregion}
}

ExpireType枚举

ExpireType枚举标识缓存的过期类型,分为绝对过期相对过期两个类型。
绝对过期:即自创建一段时间后就过期
相对过期:即该键未被访问后一段时间后过期,若此键一直被访问则过期时间自动延长。

namespace CacheHelper
{public enum ExpireType{/// /// 绝对过期/// 注:即自创建一段时间后就过期/// Absolute,/// /// 相对过期/// 注:即该键未被访问后一段时间后过期,若此键一直被访问则过期时间自动延长/// Relative,}
}

CacheType 枚举

是使用MemoryCache,还是RedisMemoryCache不支持分布式,Redis支持分布式。

namespace CacheHelper
{public enum CacheType{/// /// 使用内存缓存(不支持分布式)/// Memory,/// /// 使用Redis缓存(支持分布式)/// Redis}
}

CacheHelper 缓存帮助类

namespace CacheHelper
{public class CacheHelper : ICache{readonly IDistributedCache _cache;public CacheHelper(IDistributedCache cache){_cache = cache;}protected string BuildKey(string idKey){return $"Cache_{GetType().FullName}_{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, TimeSpan timeout){string cacheKey = BuildKey(key);_cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpiration = new DateTimeOffset(DateTime.Now + timeout)});}public async Task SetCacheAsync(string key, object value, TimeSpan timeout){string cacheKey = BuildKey(key);await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpiration = new DateTimeOffset(DateTime.Now + timeout)});}public void SetCache(string key, object value, TimeSpan timeout, ExpireType expireType){string cacheKey = BuildKey(key);if (expireType == ExpireType.Absolute){//这里没转换标准时间,Linux时区会有问题?_cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpiration = new DateTimeOffset(DateTime.Now + timeout)});}else{_cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpirationRelativeToNow = timeout});}}public async Task SetCacheAsync(string key, object value, TimeSpan timeout, ExpireType expireType){string cacheKey = BuildKey(key);if (expireType == ExpireType.Absolute){//这里没转换标准时间,Linux时区会有问题?await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpiration = new DateTimeOffset(DateTime.Now + timeout)});}else{await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions{AbsoluteExpirationRelativeToNow = timeout});}}public string GetCache(string idKey){if (idKey.IsNullOrEmpty()){return null;}string cacheKey = BuildKey(idKey);var cache = _cache.GetString(cacheKey);return cache;}public async Task GetCacheAsync(string key){if (key.IsNullOrEmpty()){return null;}string cacheKey = BuildKey(key);var cache = await _cache.GetStringAsync(cacheKey);return cache;}public T GetCache(string key){var cache = GetCache(key);if (!cache.IsNullOrEmpty()){return cache.ToObject();}return default(T);}public async Task GetCacheAsync(string key){var cache = await GetCacheAsync(key);if (!string.IsNullOrEmpty(cache)){return cache.ToObject();}return default(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));}}
}

CacheHelper 中,自定义了一个string的扩展方法ToObject()ToObject()扩展方法使用了 Newtonsoft.Json

/// 
/// 将Json字符串反序列化为对象
/// 
/// 对象类型
/// Json字符串
/// 
public static T ToObject(this string jsonStr)
{return JsonConvert.DeserializeObject(jsonStr);
}

CacheHelper 的使用方法

安装Redis依赖

Redis依赖我使用的是Caching.CSRedis,安装依赖:

PM> Install-Package Caching.CSRedis -Version 3.6.90

配置appsettings.json

在appsettings.json中,对缓存进行配置:

 "Cache": {"CacheType": "Memory", // "Memory OR Redis""RedisEndpoint": "127.0.0.1:6379" //Redis节点地址,定义详见 https://github.com/2881099/csredis},

如果要使用MemoryCache,CacheType就设置为Memory,如果要使用Redis,CacheType就设置为Redis。如果设置为Redis的话,还需要配置RedisEndpoint,保证Redis节点可用。

CacheOptions配置

编写一个名为CacheOptions的类。用于获取配置文件的配置节内容

namespace CacheHelper
{public class CacheOptions{public CacheType CacheType { get; set; }public string RedisEndpoint { get; set; }}
}

IHostBuilder扩展方法UseCache

编写一个IHostBuilder的扩展方法UseCache,用于注入MemoryCache或是Redis

public static IHostBuilder UseCache(this IHostBuilder hostBuilder)
{hostBuilder.ConfigureServices((buidlerContext, services) =>{var cacheOption = buidlerContext.Configuration.GetSection("Cache").Get();switch (cacheOption.CacheType){case CacheType.Memory: services.AddDistributedMemoryCache(); break;case CacheType.Redis:{var csredis = new CSRedisClient(cacheOption.RedisEndpoint);RedisHelper.Initialization(csredis);services.AddSingleton(csredis);services.AddSingleton(new CSRedisCache(RedisHelper.Instance));}; break;default: throw new Exception("缓存类型无效");}});return hostBuilder;
}

Program.cs中引用

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseCache();

CacheHelper的使用。

public class HomeController
{readonly ICache _cache;public HomeController(ICache cache,){_cache = cache;}public async Task CacheTest(string key){string cache_value = "hello cache";//同步方法_cache.SetCache(key,cache_value );string v = _cache.GetCache(key);_cache.RemoveCache(key);//异步方法await _cache.SetCacheAsync(key,cache_value );string val = await _cache.GetCacheAsync(key);await _cache.RemoveCacheAsync(key);}
}

总结

暂无,下次再会

相关内容

热门资讯

“我真的撑不住了”,2000万... 5月14日、15日两天,知名搞笑博主“大连老湿王博文”,分别在微信公众号和小红书上发表长文,宣布断更...
原创 9... 邱 林 没有想到的是,日本对中东地区石油依赖度竟高达96%,其中,阿联酋占43%,沙特阿拉伯占39%...
华金策略:A股短期可能难大调整... 来源:市场资讯 来源:华金证券 投资要点 复盘历史,驱动TMT行情结束的核心因素是外部事件和政策偏空...
5月18日突然大跌,金价行情拐... 刚刷完5月18日凌晨的金价数据,伦敦金现直接暴跌113.8美元,报4537.83美元/盎司,单日跌幅...
深化资本与产业协同 打造AI智... 央广网北京5月18日消息(记者 郭彦伟)“这款熊猫医生AI机器人主要能帮助大家实现生命体征检测、AI...
实地调研深圳融资市场 细数贷款... 在当下经济发展节奏较快的深圳,各行各业的资金周转需求愈发普遍,从个体日常大额支出、家庭置业规划,到个...
上市公司交出近三年最好成绩单 ... 上市公司是经济高质量发展的重要微观基础,稳中向好的成绩单有力印证中国经济的强大韧性与活力。从上市公司...
接连吃罚单!这家券商债券业务“... 5月15日,国都证券及其债券从业人员收到了北京证监局发出的5份行政处罚。 罚单显示,因在公司债券承销...
原创 美... 特朗普本次的中国之行,其深远影响将直接牵动美国今年中期选举的最终走向,因此,他此番远渡重洋,无疑是怀...
AI高景气与盈利持续兑现 机构... 存储芯片指数日K线图   范雨露 制图 上周,全球主要股指普遍回调,A股市场同样冲高回落,创业板指创...
2026天津房交会暨“新房市集... 近日,2026天津房交会暨“新房市集”活动在津一·PARK正式启幕。此次房交会由天津市房地产市场服务...
原创 【... 各位朋友,最近是不是感觉金店门口的“今日金价”牌子,数字变得有点“刺眼”?没错,黄金它……真的跌了,...
原创 推... 俄罗斯财长安东·西卢安诺夫接受自家媒体采访,透露了两条重磅消息。 第一个:中俄双边贸易中,本币结算率...
兆易创新盘中涨停续创历史新高 ... 5月18日早盘,兆易创新盘中涨停,股价续创历史新高,报412.87元/股,成交金额超130亿元,A+...
原创 价... 过去三年价格战硝烟弥漫,汽车价格一降再降。 然而曾经杀得眼红的车企们,如今集体踩下刹车,汽车售价不降...
4月居民贷款大幅缩水近8000... 一边是楼市延续修复态势,“小阳春”行情持续演绎,重点城市二手房成交量大幅攀升;另一边是居民信贷数据的...
金价暴涨里的“套保”迷影,山东... 山东黄金冶炼业务。图源:企业官网 本报(chinatimes.net.cn)记者张蓓 黄指南 深圳报...
扬帆出海获佳绩!盐田区携手黄金... 2026年5月8日至10日 在马来西亚槟城举办的 “2026马来西亚黄金珠宝展销会”上 深圳市盐田区...
政策底与情绪顶:5月18日-2... 文/金透社 万捷 2026年5月第三周(5月11日-15日),A股市场走出了鲜明的分化格局。上证指数...
证监会重罚欺诈发行,广发证券被... 4.63亿元。 这是2026年5月,证监会对清越科技、元道通信两家公司欺诈发行、财务造假的罚款总额。...