using Furion.DependencyInjection; using Microsoft.Extensions.Caching.Memory; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; namespace Magic.Core; /// /// 内存缓存 /// public class MemoryCache : ICache, ISingleton { private readonly IMemoryCache _memoryCache; public MemoryCache(IMemoryCache memoryCache) { _memoryCache = memoryCache; } public long Del(params string[] key) { foreach (var k in key) { _memoryCache.Remove(k); } return key.Length; } public Task DelAsync(params string[] key) { foreach (var k in key) { _memoryCache.Remove(k); } return Task.FromResult((long)key.Length); } public async Task DelByPatternAsync(string pattern) { if (string.IsNullOrEmpty(pattern)) return default; //pattern = Regex.Replace(pattern, @"\{*.\}", "(.*)"); var keys = GetAllKeys().Where(k => k.StartsWith(pattern)); if (keys != null && keys.Any()) return await DelAsync(keys.ToArray()); return default; } public bool Exists(string key) { return _memoryCache.TryGetValue(key, out _); } public Task ExistsAsync(string key) { return Task.FromResult(_memoryCache.TryGetValue(key, out _)); } public string Get(string key) { return _memoryCache.Get(key)?.ToString(); } public T Get(string key) { return _memoryCache.Get(key); } public Task GetAsync(string key) { return Task.FromResult(Get(key)); } public Task GetAsync(string key) { return Task.FromResult(Get(key)); } public bool Set(string key, object value) { _memoryCache.Set(key, value); return true; } public bool Set(string key, object value, TimeSpan expire) { _memoryCache.Set(key, value, expire); return true; } public Task SetAsync(string key, object value) { Set(key, value); return Task.FromResult(true); } public Task SetAsync(string key, object value, TimeSpan expire) { Set(key, value, expire); return Task.FromResult(true); } public List GetAllKeys() { //const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic; //var entries = _memoryCache.GetType().GetField("_entries", flags)?.GetValue(_memoryCache); //var cacheItems = entries?.GetType().GetProperty("Keys").GetValue(entries) as ICollection; //entries as IDictionary; //var keys = new List(); //if (cacheItems == null) return keys; //return cacheItems.Select(u => u.ToString()).ToList(); const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic; var entries = _memoryCache.GetType().GetField("_coherentState", flags)?.GetValue(_memoryCache); var cacheItems = entries?.GetType().GetProperty("EntriesCollection", flags).GetValue(entries) as ICollection; //entries as IDictionary; var keys = new List(); if (cacheItems == null) return keys; foreach (var item in cacheItems) { var methodInfo = item.GetType().GetProperty("Key"); var val = methodInfo.GetValue(item); keys.Add(val.ToString()); } return keys; } }