IMemoryCache:内存缓存接口,内存缓存可以存储任何对象,存储形式键值对
IDistributedCache:分布式缓存接口(Redis、MongoDB、DB...)
IDistributedCache:
public interface IDistributedCache {
//获取 byte[] Get(string key); Task<byte[]> GetAsync(string key, CancellationToken token = default(CancellationToken)); //刷新并重置其过期超时的值(如果有) void Refresh(string key); Task RefreshAsync(string key, CancellationToken token = default(CancellationToken)); //删除 void Remove(string key); Task RemoveAsync(string key, CancellationToken token = default(CancellationToken)); //添加 void Set(string key, byte[] value, DistributedCacheEntryOptions options); Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default(CancellationToken)); }
MemoryCache内存缓存使用步骤:
1、安装程序集:System.Runtime.Caching 和 Microsoft.Extensions.Caching.Memory,如果是是Core MVC程序自带的Microsoft.AspNetCore.App包里已经涵盖了 Microsoft.Extensions.Caching.Memory,无需重复下载。
2、在ConfigureService中注册内存缓存服务: services.AddMemoryCache();
3、构造函数注入 IMemoryCache
Redis缓存使用步骤:
安装 Microsoft.Extensions.Caching.Redis包,
直接使用:(RedisCache实现了接口IDistributedCache)
static void Main(string[] args) { RedisCache redisCache = new RedisCache(new RedisCacheOptions() { Configuration="192.168.254.134:6379", InstanceName="test" }); redisCache.SetString("key","value"); var val = redisCache.GetString("key"); }
在MVC中使用,ConfigureService中添加以下代码:
//将Redis分布式缓存服务添加到服务中 services.AddDistributedRedisCache(options => { //options.Configuration = "139.155.44.138:6379"; //Redis实例名 options.InstanceName = "RedisDistributedCache"; options.ConfigurationOptions = new ConfigurationOptions() { ConnectTimeout = 2000, DefaultDatabase = 1, //Password = "xxxxxx", AllowAdmin = true, AbortOnConnectFail = false,//当为true时,当没有可用的服务器时则不会创建一个连接 }; options.ConfigurationOptions.EndPoints.Add("139.155.44.138:6379"); });
需要缓存的服务中注入IDistributedCache即可:
public HomeController(IDistributedCache Cache){}
MongoDB缓存使用步骤:
安装 MarkCBB.Extensions.Caching.MongoDB 包
直接使用:
static void Main(string[] args) { MongoDBCache mongoDBCache = new MongoDBCache(new MongoDBCacheOptions() { ConnectionString = "mongodb://192.168.254.135:27017", DatabaseName = "sample", CollectionName = "sample" }); mongoDBCache.Set("username", Encoding.UTF8.GetBytes("jack"), new DistributedCacheEntryOptions() { AbsoluteExpiration = DateTime.Now.AddDays(1) }); var info = mongoDBCache.GetString("username"); }
案例1:使用ICaching接口封装MemoryCache、RedisCache操作。自己选择内存或分布式缓存
ICaching接口:
public interface ICaching { T GetOrSetObjectFromCache<T>(string cacheItemName, Func<T> objectSettingFunction, int cacheTimeInMinutes = 0); void SetValueToCache(string key, object value, int cacheTimeInMinutes = 120);
void Invalidate(string key); void InvalidateAll(); object GetValueFromCache(string key); }
MemoryCaching、RedisCaching实现类:
/// <summary> /// EasyMemoryCache /// https://github.com/thiagoloureiro/EasyMemoryCache /// </summary> public class MemoryCaching : ICaching, IDisposable { private readonly MemoryCache _myCache = new MemoryCache(new MemoryCacheOptions()); private readonly IConfiguration _configuration; private readonly int _cacheTime; public MemoryCaching(IConfiguration configuration) { this._configuration = configuration; _cacheTime = this._configuration.GetValue<int>("CACHE_TIME"); } public void Dispose() { this._myCache?.Dispose(); } public T GetOrSetObjectFromCache<T>(string cacheItemName, Func<T> objectSettingFunction, int cacheTimeInMinutes = 0) { T cacheObject = default(T); var cacheObj = this._myCache.Get(cacheItemName); if (cacheObj != null) { cacheObject = (T)cacheObj; } else { cacheObject = objectSettingFunction(); this._myCache.Set(cacheItemName, cacheObject, DateTime.Now.AddMinutes(cacheTimeInMinutes == 0 ? _cacheTime : cacheTimeInMinutes)); } return cacheObject; } public void SetValueToCache(string key, object value, int cacheTimeInMinutes = 120) { this._myCache.Set(key, value, DateTimeOffset.Now.AddMinutes(cacheTimeInMinutes)); } public object GetValueFromCache(string key) { return this._myCache.Get(key); } public void Invalidate(string key) { this._myCache.Remove(key); } public void InvalidateAll() { var field = typeof(MemoryCache).GetProperty("EntriesCollection", BindingFlags.NonPublic | BindingFlags.Instance); if (field != null) { var collection = field.GetValue(this._myCache) as ICollection; var items = new List<string>(); if (collection != null) foreach (var item in collection) { var methodInfo = item.GetType().GetProperty("Key"); if (methodInfo != null) { var val = methodInfo.GetValue(item); items.Add(val.ToString()); } } foreach (var item in items) { this._myCache.Remove(item); } } } } /// <summary> /// RedisCache /// </summary> public class RedisCaching : ICaching, IDisposable { private readonly IDistributedCache _myCache;// = new RedisCache(new RedisCacheOptions()); private readonly IConfiguration _configuration; private readonly int _cacheTime; public RedisCaching(IConfiguration configuration, IDistributedCache cache) { this._configuration = configuration; _cacheTime = this._configuration.GetValue<int>("CACHE_TIME"); _myCache = cache; } public void Dispose() { //this._myCache?.Dispose(); } public T GetOrSetObjectFromCache<T>(string cacheItemName, Func<T> objectSettingFunction, int cacheTimeInMinutes = 0) { T cacheObject = default(T); byte[] cacheObj = this._myCache.Get(cacheItemName); if (cacheObj != null) { var stringObject = Encoding.UTF8.GetString(cacheObj);//通过UTF-8编码,将字节数组反序列化为Json字符串 cacheObject = JsonConvert.DeserializeObject<T>(stringObject, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }); } else { cacheObject = objectSettingFunction(); var stringObject = JsonConvert.SerializeObject(cacheObject, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, TypeNameHandling = TypeNameHandling.All }); var bytesObject = Encoding.UTF8.GetBytes(stringObject);//将Json字符串通过UTF-8编码,序列化为字节数组 this._myCache.Set(cacheItemName, bytesObject, new DistributedCacheEntryOptions() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(cacheTimeInMinutes == 0 ? _cacheTime : cacheTimeInMinutes) }); } this._myCache.Refresh(cacheItemName); return cacheObject; } public void SetValueToCache(string key, object value, int cacheTimeInMinutes = 120) { var stringObject = JsonConvert.SerializeObject(value, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, TypeNameHandling = TypeNameHandling.All }); var bytesObject = Encoding.UTF8.GetBytes(stringObject);//将Json字符串通过UTF-8编码,序列化为字节数组 this._myCache.Set(key, bytesObject, new DistributedCacheEntryOptions() { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(cacheTimeInMinutes) }); } /// <summary> /// 从Redis中刷新键值 /// </summary> /// <param name="key">缓存键</param> public void Refresh(string key) { this._myCache.Refresh(key); } public object GetValueFromCache(string key) { return this._myCache.Get(key); } public void Invalidate(string key) { this._myCache.Remove(key); } public void InvalidateAll() { throw new NotImplementedException(); } }
ConfigureServices:
services.AddDistributedRedisCache(options => { ConfigurationOptions configurationOptions = new ConfigurationOptions { ConnectTimeout = 2000, DefaultDatabase = 1, Password = "315360007", AllowAdmin = true, AbortOnConnectFail = false//当为true时,当没有可用的服务器时则不会创建一个连接 }; configurationOptions.EndPoints.Add("192.168.0.82:16379"); options.ConfigurationOptions = configurationOptions; }); services.AddSingleton(typeof(ICaching), typeof(MemoryCaching)); //services.AddSingleton(typeof(ICaching), typeof(RedisCaching));
未完待续...