NET Core 3.1 基於Autofac 的緩存AOP


緩存功能,一般咱們都是將數據獲取到以后,定義緩存,然后在其他地方使用的時候,在根據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、定義一個緩存攔截器

還是繼承IInterceptor,並實現Intercept

 

/// <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、運行,查看效果

你會發現,首次緩存是空的,然后將Repository倉儲中取出來的數據存入緩存,第二次使用就是有值了,其他所有的地方使用,都不用再寫了,而且也是面向整個程序集合的

 

 

 

 安裝大神代碼實現了,詳情參照 https://www.cnblogs.com/laozhang-is-phi/p/9547574.html

此處記錄方便以后查找


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM