• 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

    此处记录方便以后查找

  • 相关阅读:
    1654. Minimum Jumps to Reach Home
    1129. Shortest Path with Alternating Colors
    1766. Tree of Coprimes
    1368. Minimum Cost to Make at Least One Valid Path in a Grid
    LeetCode 841 钥匙与房间
    LeetCode 268 缺失数字
    LeetCode 136 只出现一次的数字
    LeetCode 461 汉明距离
    LeetCode 557 反转字符串中的单词 III
    LeetCode 392 判断子序列
  • 原文地址:https://www.cnblogs.com/shuaichao/p/12402909.html
Copyright © 2020-2023  润新知