緩存功能,一般咱們都是將數據獲取到以后,定義緩存,然后在其他地方使用的時候,在根據key去獲取當前數據,然后再操作等等,平時都是在API接口層獲取數據后進行緩存,今天咱們可以試試,在接口之前就緩存下來。
1、定義 Memory 緩存類和接口
/// <summary> /// 簡單的緩存接口,只有查詢和添加,以后會進行擴展 /// </summary> public interface ICaching { object Get(string cacheKey); void Set(string cacheKey, object cacheValue); } /// <summary> /// 實例化緩存接口ICaching /// </summary> public class MemoryCaching : ICaching { //引用Microsoft.Extensions.Caching.Memory;這個和.net 還是不一樣,沒有了Httpruntime了 private IMemoryCache _cache; //還是通過構造函數的方法,獲取 public MemoryCaching(IMemoryCache cache) { _cache = cache; } public object Get(string cacheKey) { return _cache.Get(cacheKey); } public void Set(string cacheKey, object cacheValue) { _cache.Set(cacheKey, cacheValue, TimeSpan.FromSeconds(7200)); } }
2、定義一個緩存攔截器
/// <summary> /// 面向切面的緩存使用 /// </summary> public class BlogCacheAOP : IInterceptor { //通過注入的方式,把緩存操作接口通過構造函數注入 private ICaching _cache; public BlogCacheAOP(ICaching cache) { _cache = cache; } //Intercept方法是攔截的關鍵所在,也是IInterceptor接口中的唯一定義 public void Intercept(IInvocation invocation) { //獲取自定義緩存鍵 var cacheKey = CustomCacheKey(invocation); //根據key獲取相應的緩存值 var cacheValue = _cache.Get(cacheKey); if (cacheValue != null) { //將當前獲取到的緩存值,賦值給當前執行方法 invocation.ReturnValue = cacheValue; return; } //去執行當前的方法 invocation.Proceed(); //存入緩存 if (!string.IsNullOrWhiteSpace(cacheKey)) { _cache.Set(cacheKey, invocation.ReturnValue); } } //自定義緩存鍵 private string CustomCacheKey(IInvocation invocation) { var typeName = invocation.TargetType.Name; var methodName = invocation.Method.Name; var methodArguments = invocation.Arguments.Select(GetArgumentValue).Take(3).ToList();//獲取參數列表,我最多需要三個即可 string key = $"{typeName}:{methodName}:"; foreach (var param in methodArguments) { key += $"{param}:"; } return key.TrimEnd(':'); } //object 轉 string private string GetArgumentValue(object arg) { if (arg is int || arg is long || arg is string) return arg.ToString(); if (arg is DateTime) return ((DateTime)arg).ToString("yyyyMMddHHmmss"); return ""; } }
3、注入緩存攔截器
Startup 的 ConfigureContainer 方法
var cacheType = new List<Type>(); builder.RegisterType<BlogLogAOP>(); cacheType.Add(typeof(BlogLogAOP)); // 獲取 Service.dll 程序集服務,並注冊 var assemblysServices = Assembly.LoadFrom(servicesDllFile); builder.RegisterAssemblyTypes(assemblysServices) .AsImplementedInterfaces() .InstancePerDependency() .EnableInterfaceInterceptors()//引用Autofac.Extras.DynamicProxy; .InterceptedBy(cacheType.ToArray());//允許將攔截器服務的列表分配給注冊。
3、啟動緩存
/// <summary> /// 緩存服務啟動 /// </summary> public static class MemoryCacheSetup { public static void AddMemoryCacheSetup(this IServiceCollection services) { if (services == null) throw new ArgumentNullException(nameof(services)); services.AddScoped<ICaching, MemoryCaching>(); services.AddSingleton<IMemoryCache>(factory => { var cache = new MemoryCache(new MemoryCacheOptions()); return cache; }); } }
Startup 的 ConfigureServices 方法
//注入緩存 services.AddMemoryCacheSetup();
4、運行,查看效果
安裝大神代碼實現了,詳情參照 https://www.cnblogs.com/laozhang-is-phi/p/9547574.html
此處記錄方便以后查找