using Microsoft.Extensions.Caching.Memory; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; namespace UCFAR.AI.Common.Cache { public class MemoryCacheService : ICacheService { protected IMemoryCache Cache; public MemoryCacheService(IMemoryCache cache) { Cache = cache; } public static MemoryCacheService Default { get; private set; } static MemoryCacheService() { Default = new MemoryCacheService(new MemoryCache(new MemoryCacheOptions())); } /// <summary> /// 是否存在此缓存 /// </summary> /// <param name="key"></param> /// <returns></returns> public bool Exists(string key) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); return Cache.TryGetValue<object>(key, out _); } /// <summary> /// 取得缓存数据 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key"></param> /// <returns></returns> public T GetCache<T>(string key) where T : class { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); Cache.TryGetValue(key, out T v); return v; } /// <summary> /// 设置缓存 /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void SetCache(string key, object value) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); object v = null; if (Cache.TryGetValue(key, out v)) Cache.Remove(key); Cache.Set(key, value); } /// <summary> /// 设置缓存,绝对过期 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expirationMinute">间隔分钟</param> /// MemoryCacheService.Default.SetCache("test", "RedisCache works!", 30); public void SetCache(string key, object value, double expirationMinute) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); object v = null; if (Cache.TryGetValue(key, out v)) Cache.Remove(key); DateTime now = DateTime.Now; TimeSpan ts = now.AddMinutes(expirationMinute) - DateTime.Now; Cache.Set(key, value, ts); } /// <summary> /// 设置缓存,绝对过期 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="expirationTime">DateTimeOffset 结束时间</param> /// MemoryCacheService.Default.SetCache("test", "RedisCache works!", DateTimeOffset.Now.AddSeconds(30)); public void SetCache(string key, object value, DateTimeOffset expirationTime) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); if (Cache.TryGetValue(key, out _)) Cache.Remove(key); Cache.Set(key, value, expirationTime); } /// <summary> /// 设置缓存,相对过期时间 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="t"></param> /// MemoryCacheService.Default.SetCache("test", "MemoryCache works!",TimeSpan.FromSeconds(30)); public void SetSlidingCache(string key, object value, TimeSpan t) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); if (value == null) throw new ArgumentNullException(nameof(value)); if (Cache.TryGetValue(key, out _)) Cache.Remove(key); Cache.Set(key, value, new MemoryCacheEntryOptions() { SlidingExpiration = t }); } /// <summary> /// 移除缓存 /// </summary> /// <param name="key"></param> public void RemoveCache(string key) { if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key)); Cache.Remove(key); } /// <summary> /// 释放 /// </summary> public void Dispose() { Cache?.Dispose(); GC.SuppressFinalize(this); } #region 增加 /// <summary> /// 添加缓存 /// </summary> /// <param name="key">缓存Key</param> /// <param name="value">缓存Value</param> /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param> /// <param name="expiressAbsoulte">绝对过期时长</param> /// <returns></returns> public bool Set(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 Set(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)); Cache.Set(key, value, isSliding ? new MemoryCacheEntryOptions().SetSlidingExpiration(expiresIn) : new MemoryCacheEntryOptions().SetAbsoluteExpiration(expiresIn)); return Exists(key); } #region 删除缓存 /// <summary> /// 删除缓存 /// </summary> /// <param name="key">缓存Key</param> /// <returns></returns> public void Remove(string key) { if (key == null) throw new ArgumentNullException(nameof(key)); Cache.Remove(key); } /// <summary> /// 批量删除缓存 /// </summary> /// <returns></returns> public void RemoveAll(IEnumerable<string> keys) { if (keys == null) throw new ArgumentNullException(nameof(keys)); keys.ToList().ForEach(item => Cache.Remove(item)); } #endregion #region 获取缓存 /// <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; } #endregion /// <summary> /// 删除所有缓存 /// </summary> public void RemoveCacheAll() { var l = GetCacheKeys(); foreach (var s in l) { Remove(s); } } /// <summary> /// 删除匹配到的缓存 /// </summary> /// <param name="pattern"></param> /// <returns></returns> public void RemoveCacheRegex(string pattern) { IList<string> l = SearchCacheRegex(pattern); foreach (var s in l) { Remove(s); } } /// <summary> /// 搜索 匹配到的缓存 /// </summary> /// <param name="pattern"></param> /// <returns></returns> public IList<string> SearchCacheRegex(string pattern) { var cacheKeys = GetCacheKeys(); var l = cacheKeys.Where(k => Regex.IsMatch(k, pattern)).ToList(); return l.AsReadOnly(); } /// <summary> /// 获取所有缓存键 /// </summary> /// <returns></returns> public List<string> GetCacheKeys() { const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic; var entries = Cache.GetType().GetField("_entries", flags)?.GetValue(Cache); var cacheItems = entries as IDictionary; var keys = new List<string>(); if (cacheItems == null) return keys; foreach (DictionaryEntry cacheItem in cacheItems) { keys.Add(cacheItem.Key.ToString()); } return keys; } #endregion } }
原文:https://www.cnblogs.com/ucfar/p/11431946.html