缓存接口 ICacheService
using System; using System.Collections.Generic; using System.Threading.Tasks; namespace WebAppNetCore.Interface { public interface ICacheService { /// <summary> /// 验证缓存项是否存在 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> bool Exists(string key); /// <summary> /// 验证缓存项是否存在(异步方式) /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> Task<bool> ExistsAsync(string key); /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <returns></returns> bool Add(string key, object value); /// <summary> /// 添加缓存(异步方式) /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <returns></returns> Task<bool> AddAsync(string key, object value); /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <param name="expiressAbsoulte">绝对过期时长</param> /// <returns></returns> bool Add(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte); /// <summary> /// 添加缓存(异步方式) /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <param name="expiressAbsoulte">绝对过期时长</param> /// <returns></returns> Task<bool> AddAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte); /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresIn">缓存时长</param> /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <returns></returns> bool Add(string key, object value, TimeSpan expiresIn, bool isSliding = false); /// <summary> /// 添加缓存(异步方式) /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresIn">缓存时长</param> /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <returns></returns> Task<bool> AddAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false); /// <summary> /// 删除缓存 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> bool Remove(string key); /// <summary> /// 删除缓存(异步方式) /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> Task<bool> RemoveAsync(string key); /// <summary> /// 批量删除缓存 /// </summary> /// <param name="key">缓存Key集合</param> /// <returns></returns> void RemoveAll(IEnumerable<string> keys); /// <summary> /// 批量删除缓存(异步方式) /// </summary> /// <param name="key">缓存Key集合</param> /// <returns></returns> Task RemoveAllAsync(IEnumerable<string> keys); /// <summary> /// 获取缓存 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> T Get<T>(string key) where T : class; /// <summary> /// 获取缓存(异步方式) /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> Task<T> GetAsync<T>(string key) where T : class; /// <summary> /// 获取缓存 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> object Get(string key); /// <summary> /// 获取缓存(异步方式) /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> Task<object> GetAsync(string key); /// <summary> /// 获取缓存集合 /// </summary> /// <param name="keys">缓存Key集合</param> /// <returns></returns> IDictionary<string, object> GetAll(IEnumerable<string> keys); /// <summary> /// 获取缓存集合(异步方式) /// </summary> /// <param name="keys">缓存Key集合</param> /// <returns></returns> Task<IDictionary<string, object>> GetAllAsync(IEnumerable<string> keys); /// <summary> /// 修改缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <returns></returns> bool Replace(string key, object value); /// <summary> /// 修改缓存(异步方式) /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <returns></returns> //Task<bool> ReplaceAsync(string key, object value); /// <summary> /// 修改缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <param name="expiressAbsoulte">绝对过期时长</param> /// <returns></returns> bool Replace(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte); /// <summary> /// 修改缓存(异步方式) /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <param name="expiressAbsoulte">绝对过期时长</param> /// <returns></returns> //Task<bool> ReplaceAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte); /// <summary> /// 修改缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <param name="expiresIn">缓存时长</param> /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <returns></returns> bool Replace(string key, object value, TimeSpan expiresIn, bool isSliding = false); /// <summary> /// 修改缓存(异步方式) /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <param name="expiresIn">缓存时长</param> /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <returns></returns> //Task<bool> ReplaceAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false); } }
缓存实现类 MemoryCacheService
using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using WebAppNetCore.Interface; namespace WebAppNetCore.Services { public class MemoryCacheService : ICacheService { protected IMemoryCache _cache; public MemoryCacheService(IMemoryCache cache) { _cache = cache; } /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <returns></returns> public bool Add(string key, object value) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } _cache.Set(key, value); return Exists(key); } /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <param name="expiressAbsoulte">绝对过期时长</param> /// <returns></returns> public bool Add(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } _cache.Set(key, value, new MemoryCacheEntryOptions() .SetSlidingExpiration(expiresSliding) .SetAbsoluteExpiration(expiressAbsoulte) ); return Exists(key); } /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresIn">缓存时长</param> /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <returns></returns> public bool Add(string key, object value, TimeSpan expiresIn, bool isSliding = false) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } if (isSliding) _cache.Set(key, value, new MemoryCacheEntryOptions() .SetSlidingExpiration(expiresIn) ); else _cache.Set(key, value, new MemoryCacheEntryOptions() .SetAbsoluteExpiration(expiresIn) ); return Exists(key); } public Task<bool> AddAsync(string key, object value) { throw new NotImplementedException(); } public Task<bool> AddAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte) { throw new NotImplementedException(); } public Task<bool> AddAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false) { throw new NotImplementedException(); } /// <summary> /// 验证缓存项是否存在 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> public bool Exists(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } object cached; return _cache.TryGetValue(key, out cached); } public Task<bool> ExistsAsync(string key) { throw new NotImplementedException(); } /// <summary> /// 获取缓存 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> public T Get<T>(string key) where T : class { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.Get(key) as T; } /// <summary> /// 获取缓存 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> public object Get(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.Get(key); } /// <summary> /// 获取缓存集合 /// </summary> /// <param name="keys">缓存Key集合</param> /// <returns></returns> public IDictionary<string, object> GetAll(IEnumerable<string> keys) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } var dict = new Dictionary<string, object>(); keys.ToList().ForEach(item => dict.Add(item, _cache.Get(item))); return dict; } public Task<IDictionary<string, object>> GetAllAsync(IEnumerable<string> keys) { throw new NotImplementedException(); } public Task<T> GetAsync<T>(string key) where T : class { throw new NotImplementedException(); } public Task<object> GetAsync(string key) { throw new NotImplementedException(); } /// <summary> /// 删除缓存 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> public bool Remove(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } _cache.Remove(key); return !Exists(key); } /// <summary> /// 批量删除缓存 /// </summary> /// <param name="key">缓存Key集合</param> /// <returns></returns> public void RemoveAll(IEnumerable<string> keys) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } keys.ToList().ForEach(item => _cache.Remove(item)); } public Task RemoveAllAsync(IEnumerable<string> keys) { throw new NotImplementedException(); } public Task<bool> RemoveAsync(string key) { throw new NotImplementedException(); } /// <summary> /// 修改缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <returns></returns> public bool Replace(string key, object value) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } if (Exists(key)) if (!Remove(key)) return false; return Add(key, value); } /// <summary> /// 修改缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <param name="expiressAbsoulte">绝对过期时长</param> /// <returns></returns> public bool Replace(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } if (Exists(key)) if (!Remove(key)) return false; return Add(key, value, expiresSliding, expiressAbsoulte); } /// <summary> /// 修改缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <param name="expiresIn">缓存时长</param> /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <returns></returns> public bool Replace(string key, object value, TimeSpan expiresIn, bool isSliding = false) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } if (Exists(key)) if (!Remove(key)) return false; return Add(key, value, expiresIn, isSliding); } public void Dispose() { if (_cache != null) _cache.Dispose(); GC.SuppressFinalize(this); } } }
缓存实现类 RedisCacheService
using Microsoft.Extensions.Caching.Redis; using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using WebAppNetCore.Interface; namespace WebAppNetCore.Services { public class RedisCacheService : ICacheService { protected IDatabase _cache; private ConnectionMultiplexer _connection; private readonly string _instance; public RedisCacheService(RedisCacheOptions options, int database = 0) { _connection = ConnectionMultiplexer.Connect(options.Configuration); _cache = _connection.GetDatabase(database); _instance = options.InstanceName; } /// <summary> /// 验证缓存项是否存在 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> public bool Exists(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.KeyExists(GetKeyForRedis(key)); } /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <returns></returns> public bool Add(string key, object value) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.StringSet(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value))); } /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效)</param> /// <param name="expiressAbsoulte">绝对过期时长</param> /// <returns></returns> public bool Add(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.StringSet(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)), expiressAbsoulte); } /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresIn">缓存时长</param> /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效)</param> /// <returns></returns> public bool Add(string key, object value, TimeSpan expiresIn, bool isSliding = false) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.StringSet(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)), expiresIn); } /// <summary> /// 删除缓存 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> public bool Remove(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.KeyDelete(GetKeyForRedis(key)); } /// <summary> /// 批量删除缓存 /// </summary> /// <param name="key">缓存Key集合</param> /// <returns></returns> public void RemoveAll(IEnumerable<string> keys) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } keys.ToList().ForEach(item => Remove(item)); } /// <summary> /// 获取缓存 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> public T Get<T>(string key) where T : class { if (key == null) { throw new ArgumentNullException(nameof(key)); } var value = _cache.StringGet(GetKeyForRedis(key)); if (!value.HasValue) { return default(T); } return JsonConvert.DeserializeObject<T>(value); } /// <summary> /// 获取缓存 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> public object Get(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } var value = _cache.StringGet(GetKeyForRedis(key)); if (!value.HasValue) { return null; } return JsonConvert.DeserializeObject(value); } /// <summary> /// 获取缓存集合 /// </summary> /// <param name="keys">缓存Key集合</param> /// <returns></returns> public IDictionary<string, object> GetAll(IEnumerable<string> keys) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } var dict = new Dictionary<string, object>(); keys.ToList().ForEach(item => dict.Add(item, Get(GetKeyForRedis(item)))); return dict; } /// <summary> /// 修改缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <returns></returns> public bool Replace(string key, object value) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (Exists(key)) if (!Remove(key)) return false; return Add(key, value); } /// <summary> /// 修改缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <param name="expiressAbsoulte">绝对过期时长</param> /// <returns></returns> public bool Replace(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (Exists(key)) if (!Remove(key)) return false; return Add(key, value, expiresSliding, expiressAbsoulte); } /// <summary> /// 修改缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">新的缓存Value</param> /// <param name="expiresIn">缓存时长</param> /// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <returns></returns> public bool Replace(string key, object value, TimeSpan expiresIn, bool isSliding = false) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (Exists(key)) if (!Remove(key)) return false; return Add(key, value, expiresIn, isSliding); } //这里我们写了个方法,来组合Key值和实例名,就是Key值转为 实例名+Key public string GetKeyForRedis(string key) { return _instance + key; } public void Dispose() { if (_connection != null) _connection.Dispose(); GC.SuppressFinalize(this); } } }
配置文件字段映射类
public class AppsettingConfig { public string RedisConnection { get; set; } public string InstanceName { get; set; } public bool IsRedis { get; set; } }
starup:
public void ConfigureServices(IServiceCollection services) { //注入redis或者memorycache CacheInjection.Initialize(services, _appsettingConfig.RedisConnection,_appsettingConfig.InstanceName,_appsettingConfig.IsRedis);
}
依赖注入
public class CacheInjection { public static void Initialize(IServiceCollection services,string redisCon,string instanceName,bool isRedis = false) { //注册缓存服务 services.AddMemoryCache(); if (isRedis) { //Use Redis services.AddSingleton(typeof(ICacheService), new RedisCacheService(new RedisCacheOptions { Configuration = redisCon, InstanceName = instanceName }, 0)); } else { //Use MemoryCache services.AddSingleton<IMemoryCache>(factory => { var cache = new MemoryCache(new MemoryCacheOptions()); return cache; }); services.AddSingleton<ICacheService, MemoryCacheService>(); } } }
参考文章:https://www.cnblogs.com/yuangang/p/5800113.html