Redis help class
1. 先创建缓存接口
////// 缓存接口 /// public interface ICacheRepository : IDisposable { /// /// Get a cached item. If it's not in the cache yet, then load and cache it /// /// Type of cached item /// Cache key /// Function to load item if it's not in the cache yet /// The cached value associated with the specified key T Get (CacheKey key, Func acquire) where T: class; /// /// Get a cached item. If it's not in the cache yet, then load and cache it /// /// Type of cached item /// Cache key /// Function to load item if it's not in the cache yet /// The cached value associated with the specified key Task GetAsync (CacheKey key, Func > acquire) where T : class; /// /// Removes the value with the specified key from the cache /// /// Key of cached item void Remove(CacheKey key); /// /// Adds the specified key and object to the cache /// /// Key of cached item /// Value for caching void Set(CacheKey key, object data); /// /// Gets a value indicating whether the value associated with the specified key is cached /// /// Key of cached item /// True if item already is in cache; otherwise false bool IsSet(CacheKey key); /// /// Removes items by key prefix /// /// String key prefix void RemoveByPrefix(string prefix); /// /// Clear all cache data /// void Clear(); }
2. redis类
public class RedisCacheRepository : ICacheRepository { private bool _disposed; private readonly ILogger_logger; private readonly ConnectionMultiplexer _redis; private readonly IDatabase _db; private readonly CacheOptions _cacheOptions; public RedisCacheRepository( ILogger logger, ConnectionMultiplexer redis, IOptions cacheOptions) { _logger = logger; _redis = redis; _db = redis.GetDatabase(); _cacheOptions = cacheOptions.Value; } #region Utilities /// /// Gets the list of cache keys prefix /// /// Network address /// String key pattern /// List of cache keys protected virtual IEnumerable GetKeys(EndPoint endPoint, string prefix = null) { var server = _redis.GetServer(endPoint); //we can use the code below (commented), but it requires administration permission - ",allowAdmin=true" //server.FlushDatabase(); var keys = server.Keys(_db.Database, string.IsNullOrEmpty(prefix) ? null : $"{prefix}*"); //we should always persist the data protection key list keys = keys.Where(key => !key.ToString().Equals(_cacheOptions.RedisDataProtectionKey, StringComparison.OrdinalIgnoreCase)); return keys; } /// /// Gets the value associated with the specified key. /// /// Type of cached item /// Key of cached item /// The cached value associated with the specified key protected virtual async Task GetAsync (CacheKey key) where T : class { //get serialized item from cache var serializedItem = await _db.StringGetAsync(key.Key); if (!serializedItem.HasValue) return default; //deserialize item var item = JsonHelper.DeserializeJsonToObject (serializedItem); if (item == null) return default; return item; } /// /// Adds the specified key and object to the cache /// /// Key of cached item /// Value for caching /// Cache time in minutes protected virtual async Task SetAsync(string key, object data, int cacheTime) { if (data == null) return; //set cache time var expiresIn = TimeSpan.FromMinutes(cacheTime); //serialize item var serializedItem = JsonHelper.SerializeObject(data); //and set it to cache await _db.StringSetAsync(key, serializedItem, expiresIn); } /// /// Gets a value indicating whether the value associated with the specified key is cached /// /// Key of cached item /// True if item already is in cache; otherwise false protected virtual async Task<bool> IsSetAsync(CacheKey key) { return await _db.KeyExistsAsync(key.Key); } /// /// Attempts to execute the passed function and ignores the RedisTimeoutException if specified by settings /// /// Type of item which returned by the action /// The function to be tried to perform /// (flag indicates whether the action was executed without error, action result or default value) protected virtual (bool, T) TryPerformAction (Func action) { try { //attempts to execute the passed function var rez = action(); return (true, rez); } catch (RedisTimeoutException) { //ignore the RedisTimeoutException if specified by settings if (_cacheOptions.IgnoreRedisTimeoutException) return (false, default); //or rethrow the exception throw; } } #endregion #region Methods /// /// Get a cached item. If it's not in the cache yet, then load and cache it /// /// Type of cached item /// Cache key /// Function to load item if it's not in the cache yet /// The cached value associated with the specified key public async Task GetAsync (CacheKey key, Func > acquire) where T: class { //item already is in cache, so return it if (await IsSetAsync(key)) return await GetAsync (key); //or create it using passed function var result = await acquire(); //and set in cache (if cache time is defined) if (key.CacheTime > 0) await SetAsync(key.Key, result, key.CacheTime); return result; } /// /// Gets or sets the value associated with the specified key. /// /// Type of cached item /// Key of cached item /// The cached value associated with the specified key public virtual T Get (CacheKey key) where T: class { var (_, rez) = TryPerformAction(() => { var serializedItem = _db.StringGet(key.Key); if (!serializedItem.HasValue) return default; //deserialize item var item = JsonHelper.DeserializeJsonToObject (serializedItem); return item ?? default; }); return rez; } /// /// Get a cached item. If it's not in the cache yet, then load and cache it /// /// Type of cached item /// Cache key /// Function to load item if it's not in the cache yet /// The cached value associated with the specified key public virtual T Get (CacheKey key, Func acquire) where T : class { //item already is in cache, so return it if (IsSet(key)) { var rez = Get (key); if (rez != null && !rez.Equals(default(T))) return rez; } //or create it using passed function var result = acquire(); //and set in cache (if cache time is defined) if (key.CacheTime > 0) Set(key, result); return result; } /// /// Adds the specified key and object to the cache /// /// Key of cached item /// Value for caching public virtual void Set(CacheKey key, object data) { if (data == null) return; //set cache time var expiresIn = TimeSpan.FromMinutes(key.CacheTime); //serialize item var serializedItem = JsonHelper.SerializeObject(data); //and set it to cache TryPerformAction(() => _db.StringSet(key.Key, serializedItem, expiresIn)); } /// /// Gets a value indicating whether the value associated with the specified key is cached /// /// Key of cached item /// True if item already is in cache; otherwise false public virtual bool IsSet(CacheKey key) { var (flag, rez) = TryPerformAction(() => _db.KeyExists(key.Key)); return flag && rez; } /// /// Removes the value with the specified key from the cache /// /// Key of cached item public virtual void Remove(CacheKey key) { //we should always persist the data protection key list if (key.Key.Equals(_cacheOptions.RedisDataProtectionKey, StringComparison.OrdinalIgnoreCase)) return; //remove item from caches TryPerformAction(() => _db.KeyDelete(key.Key)); } /// /// Removes items by key prefix /// /// String key prefix public virtual void RemoveByPrefix(string prefix) { foreach (var endPoint in _redis.GetEndPoints()) { var keys = GetKeys(endPoint, prefix); TryPerformAction(() => _db.KeyDelete(keys.ToArray())); } } /// /// Clear all cache data /// public virtual void Clear() { foreach (var endPoint in _redis.GetEndPoints()) { var keys = GetKeys(endPoint).ToArray(); TryPerformAction(() => _db.KeyDelete(keys.ToArray())); } } /// /// Dispose cache manager /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } // Protected implementation of Dispose pattern. protected virtual void Dispose(bool disposing) { if (_disposed) return; _disposed = true; } #endregion }