using Microsoft.Extensions.Caching.StackExchangeRedis; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace Znyc.Cloudcar.Admin.Commons.Cache { /// /// Redis缓存操作 /// public class RedisCacheService : ICacheService { /// /// private readonly ConnectionMultiplexer _connection; /// /// private readonly string _instance; private readonly JsonSerializerOptions _jsonOptions; /// /// protected IDatabase _cache; /// /// /// /// /// public RedisCacheService(RedisCacheOptions options, JsonSerializerOptions jsonOptions, int database = 0) { _connection = ConnectionMultiplexer.Connect(options.Configuration); _cache = _connection.GetDatabase(database); _instance = options.InstanceName; _jsonOptions = jsonOptions; } /// /// /// /// public string GetKeyForRedis(string key) { return _instance + key; } public void Dispose() { if (_connection != null) { _connection.Dispose(); } GC.SuppressFinalize(this); } #region 验证缓存项是否存在 /// /// 验证缓存项是否存在 /// /// 缓存Key /// public bool Exists(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.KeyExists(GetKeyForRedis(key)); } /// /// 验证缓存项是否存在 /// /// 缓存Key /// public Task ExistsAsync(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.KeyExistsAsync(GetKeyForRedis(key)); } #endregion 验证缓存项是否存在 #region 添加缓存 /// /// 添加缓存 /// /// 缓存Key /// 缓存Value /// public bool Add(string key, object value) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.StringSet(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions))); } /// /// 添加缓存 /// /// 缓存Key /// 缓存Value /// 滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效) /// 绝对过期时长 /// 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(JsonSerializer.Serialize(value, _jsonOptions)), expiressAbsoulte); } /// /// 添加缓存 /// /// 缓存Key /// 缓存Value /// 缓存时长 /// 是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效) /// 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(JsonSerializer.Serialize(value, _jsonOptions)), expiresIn); } public Task AddAsync(string key, object value) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.StringSetAsync(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions))); } public Task AddAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.StringSetAsync(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)), expiressAbsoulte); } public Task AddAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.StringSetAsync(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)), expiresIn); } public Task HashSetAsync(string key, string filed, object value) { return _cache.HashSetAsync(GetKeyForRedis(key), Encoding.UTF8.GetBytes(JsonSerializer.Serialize(filed, _jsonOptions)), Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions))); } #endregion 添加缓存 #region 删除缓存 /// /// 删除缓存 /// /// 缓存Key /// public bool Remove(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.KeyDelete(GetKeyForRedis(key)); } /// /// 批量删除缓存 /// /// 缓存Key集合 /// public void RemoveAll(IEnumerable keys) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } keys.ToList().ForEach(item => Remove(item)); } /// /// /// /// public Task RemoveAsync(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return _cache.KeyDeleteAsync(GetKeyForRedis(key)); } public Task RemoveAllAsync(IEnumerable keys) { //if (keys == null) //{ throw new ArgumentNullException(nameof(keys)); //} //keys.ToList().ForEach(item => RemoveAsync(item)); } /// /// 使用通配符找出所有的key然后逐个删除 /// /// 通配符 public virtual void RemoveByPattern(string pattern) { foreach (System.Net.EndPoint ep in _connection.GetEndPoints()) { IServer server = _connection.GetServer(ep); IEnumerable keys = server.Keys(pattern: "*" + pattern + "*", database: _cache.Database); foreach (RedisKey key in keys) { _cache.KeyDelete(key); } } } /// /// 删除所有缓存 /// public void RemoveCacheAll() { RemoveByPattern(""); } #endregion 删除缓存 #region 获取缓存 /// /// 获取缓存 /// /// 缓存Key /// public T Get(string key) where T : class { if (key == null) { throw new ArgumentNullException(nameof(key)); } RedisValue value = _cache.StringGet(GetKeyForRedis(key)); if (!value.HasValue) { return default; } return JsonSerializer.Deserialize(value, _jsonOptions); } /// /// 获取缓存 /// /// 缓存Key /// public object Get(string key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } RedisValue value = _cache.StringGet(GetKeyForRedis(key)); if (!value.HasValue) { return null; } return JsonSerializer.Deserialize(value, _jsonOptions); //string json = value.ToString(); //return Newtonsoft.Json.JsonConvert.DeserializeObject(json); } /// /// 获取缓存集合 /// /// 缓存Key集合 /// public IDictionary GetAll(IEnumerable keys) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } Dictionary dict = new Dictionary(); keys.ToList().ForEach(item => dict.Add(item, Get(GetKeyForRedis(item)))); return dict; } public Task GetAsync(string key) where T : class { throw new NotImplementedException(); } public Task GetAsync(string key) { throw new NotImplementedException(); } public Task> GetAllAsync(IEnumerable keys) { throw new ArgumentNullException(nameof(keys)); } #endregion 获取缓存 #region 修改缓存 /// /// 修改缓存 /// /// 缓存Key /// 新的缓存Value /// 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); } /// /// 修改缓存 /// /// 缓存Key /// 新的缓存Value /// 滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间) /// 绝对过期时长 /// 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); } /// /// 修改缓存 /// /// 缓存Key /// 新的缓存Value /// 缓存时长 /// 是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间) /// 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); } public Task ReplaceAsync(string key, object value) { throw new NotImplementedException(); } public Task ReplaceAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte) { throw new NotImplementedException(); } public Task ReplaceAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false) { throw new NotImplementedException(); } #endregion 修改缓存 #region Hash /// /// /// /// /// /// public bool HSet(string key, string filed, object value) { return RedisHelper.HSet(key, filed, value); } /// /// /// /// /// /// public Task HSetAsync(string key, string filed, object value) { return RedisHelper.HSetAsync(key, filed, value); } /// /// /// /// /// public Task HMSetAsync(string key, object[] value) { return RedisHelper.HMSetAsync(key, value); } /// /// /// /// /// public bool HMSet(string key, object[] value) { return RedisHelper.HMSet(key, value); } /// /// /// /// /// public string[] HMGet(string key, string[] filed) { return RedisHelper.HMGet(key, filed); } /// /// /// /// /// public Task HMGetAsync(string key, string filed) { return RedisHelper.HMGetAsync(key, filed); } /// /// /// /// /// public long HDel(string key, string[] filed) { return RedisHelper.HDel(key, filed); } /// /// /// /// /// public Task HDelAsync(string key, string filed) { return RedisHelper.HDelAsync(key, filed); } /// /// /// /// /// public bool HExists(string key, string filed) { return RedisHelper.HExists(key, filed); } /// /// /// /// /// public Task HExistsAsync(string key, string filed) { return RedisHelper.HExistsAsync(key, filed); } /// /// /// /// /// public Task HIncrByAsync(string key, string filed) { return RedisHelper.HIncrByAsync(key, filed); } /// /// /// /// /// public long HIncrBy(string key, string filed) { return RedisHelper.HIncrBy(key, filed); } /// /// /// /// public Task> HGetAllAsync(string key) { return RedisHelper.HGetAllAsync(key); } /// /// /// /// public Dictionary HGetAll(string key) { return RedisHelper.HGetAll(key); } /// /// /// /// /// public async Task HGetAsync(string key, string filed) { return await RedisHelper.HGetAsync(key, filed); } /// /// /// /// /// /// public Task HSetNxAsync(string key, string filed, object value) { return RedisHelper.HSetNxAsync(key, filed, value); } /// /// /// /// /// /// public bool HSetNx(string key, string filed, object value) { return RedisHelper.HSetNx(key, filed, value); } #endregion Hash } }