Asp.net core Autofac 案例 注入、AOP 启用接口代理拦截 启用 类代理拦截=== 只会拦截虚方法

资料

core 实现autofac

》》》 安装 如下工具包

安装之后 如出现 这种

》》》编写 AOP类

csharp 复制代码
using Castle.DynamicProxy;
using System.Diagnostics;

namespace Web01.AOP
{
    /// <summary>
    /// 日志记录
    /// </summary>
    public class LoggingInterceptor : IInterceptor
    {
        
        public void Intercept(IInvocation invocation)
        {
            //被调用的方法名
            var methodName = invocation.Method.Name;
            //被调方法所属的类名
            var className = invocation.TargetType.Name;
            //被调用方法的参数列表
            var arguments = string.Join(", ", invocation.Arguments);
            Console.WriteLine($"方法执行之前:{className}-{methodName}-{arguments}");
            var stopwatch = Stopwatch.StartNew();
            try
            {
                //执行原始方法的逻辑 就是被调用的方法
                invocation.Proceed();
            }
            catch (Exception ex)
            {
                //输出方法执行完成的日志信息和执行时间
                Console.WriteLine($"方法执行异常: {className}.{methodName}");
                Console.WriteLine($"异常信息: {ex}");
                throw;
            }
            finally
            {
                stopwatch.Stop();
                Console.WriteLine($"方法执行之后: {className}.{methodName}");
                Console.WriteLine($"方法执行时间:{stopwatch.ElapsedMilliseconds} ms");
            }

        }
    }
}
csharp 复制代码
using Castle.DynamicProxy;
using System.Diagnostics;

namespace Web01.AOP
{
    /// <summary>
    /// 事务管理拦截器
    /// </summary>
    public class TransactionInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            var methodName = invocation.Method.Name;
            var arguments = string.Join(", ", invocation.Arguments);
            var className = invocation.TargetType.Name;
            Console.WriteLine($"Before exectiong method [方法执行之前]:{className}-{methodName}-{arguments}");

            var stopwatch= Stopwatch.StartNew();
            try
            {
                invocation.Proceed();
            }
            catch (Exception ex)
            {
                stopwatch.Stop();
                Console.WriteLine($"After executing method[ 方法执行之后]:{className}-{methodName}");
                Console.WriteLine($"Execution time[方法执行的时间]:{stopwatch.ElapsedMilliseconds} ms");
                throw;
            }
        }
    }
}

》》》接口 添加拦截器

Intercept(typeof(拦截器))\] 修饰接口,则实现接口的所有类 都会拦截,除非打标签【特性】 \[Intercept(typeof(拦截器))\] 修饰接口实现的类,则只有此类的方法会拦截。 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c6ee1d4b10be408083313da05e96287a.png) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/fdbce3d719ae422da8944c5bfb307ec8.png) ```csharp namespace Web01.Comm { public class MyAresServices : IAresServices { public void Print() { Console.WriteLine( $"MyAresServices--Print 触发" ); ; } public void Print(string name, int age) { Console.WriteLine($"MyAresServices--Print 参数为:姓名:{name}--年龄:{age}"); ; } } } ``` ```csharp using Autofac; using Autofac.Extras.DynamicProxy; using Web01.AOP; namespace Web01.Comm { ///

/// Moudle 是Autofac命名空间下面的 /// public class AutofacMoudleManager:Module { /// /// 重写Autofac管道Load 方法,load方法里面是注册注入的 /// /// protected override void Load(ContainerBuilder builder) { #region 注册 AOP //注册日志记录拦截器 builder.RegisterType(); //注册性能拦截器 builder.RegisterType(); //注册事务管理器拦截器 builder.RegisterType(); #endregion //builder.RegisterType().As(); builder.RegisterType().As().InstancePerDependency().EnableInterfaceInterceptors(); builder.RegisterType().As().InstancePerDependency().EnableInterfaceInterceptors(); // .EnableInterfaceInterceptors() // .AsImplementedInterfaces() // .InstancePerLifetimeScope() // .EnableInterfaceInterceptors() // .InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor), typeof(TransactionInterceptor)); ; //builder.RegisterType().As(); //通.InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor), typeof(TransactionInterceptor));过反射机制实现批量注册服务和拦截器 //builder.RegisterAssemblyTypes(Assembly.Load("Web01")) // .Where(a => a.Name.EndsWith("Services")) // .AsImplementedInterfaces() // .InstancePerLifetimeScope() // .EnableInterfaceInterceptors() // .InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor), typeof(TransactionInterceptor)); //.AsImplementedInterfaces():注册的服务的生命周期是默认的 Transient 生命周期 //.InstancePerLifetimeScope():每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用 //.SingleInstance():在整个应用程序生命周期中只创建一个实例,并在每次解析时重用 //.InstancePerDependency():每次解析时都创建一个新的实例 //builder.RegisterAssemblyTypes(Assembly.Load("xxxxx")) // .Where(a => a.Name.EndsWith("Services")) // .AsImplementedInterfaces() // .SingleInstance(); base.Load(builder); } } } ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/ab4832ac10264d7d9c6b24ef1b347aae.png) ```csharp builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureContainer(containerBuilder => { containerBuilder.RegisterModule(); }); ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/258235acb63148d5ac50e137ab2c46aa.png) #### 忽略拦截 声明一个 特性 , ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/16540d678f164619b657c016228adfcc.png) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/539ff802c9a54c62a799a3e2bdbb3d92.png) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/897f3d6e947140ecbbae7eda15095487.png) ```csharp if (invocation.Method.IsDefined(typeof(NeverInterceptAttribute), true)) { Console.WriteLine("=======没有被拦截=========="); invocation.Proceed(); return; } ``` [源码](https://download.csdn.net/download/u013400314/90042488) ##### 接口代理 类代理 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/880068e65cf240f4829c5c8590440509.png) ```csharp using Autofac; using Autofac.Extras.DynamicProxy; using WebApplication2.AOP; namespace WebApplication2.Coms { public class AutofacMoudleManager:Module { /// /// 重写Autofac管道Load 方法,load方法里面是注册注入的 /// /// protected override void Load(ContainerBuilder builder) { #region 注册 AOP 把拦截器注册到 autofac 容器中 //注册日志记录拦截器 //builder.RegisterType(); // 命名注入 //builder.Register(c => new LoggingInterceptor()).Named("log-record"); // 类型注入 //builder.Register(c=>new LoggingInterceptor()); builder.RegisterType(); //builder.RegisterType(typeof(LoggingInterceptor)); //注册性能拦截器 builder.RegisterType(); //注册事务管理器拦截器 builder.RegisterType(); #endregion #region 注册服务 builder.RegisterType().As(); // EnableInterfaceInterceptors方法会动态创建一个接口代理 // EnableClassInterceptors方法会创建一个目标类的子类代理类,这里需要注意的是只会拦截虚方法,重写方法 //-InstancePerLifetimeScope 每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用 //.AsImplementedInterfaces():注册的服务的生命周期是默认的 Transient 生命周期 //.SingleInstance():在整个应用程序生命周期中只创建一个实例,并在每次解析时重用 //.InstancePerDependency():每次解析时都创建一个新的实例 // 命名注册 //builder.RegisterType().Named(typeof(MyAresServices).Name).EnableClassInterceptors(); //=================启用接口代理拦截==================== //方式一:需要在接口、实现的类 添加特性 [Intercept(typeof(xxx拦截器))] ///比如 [Intercept(typeof(LoggingInterceptor))] /// 接口加 Intercept 特性,实现接口的类 全部生效 /// 实现类 加 Intercept 特性 ,只有此类 生效 //builder.RegisterType().As() // .EnableInterfaceInterceptors(); // //方式二:在 注册服务 类型到容器的时候动态注入拦截器(去掉接口、实现的类型上的特性 Intercept) 不要添加特性Intercept // InterceptedBy 支持多个拦截器 builder.RegisterType().As() .InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor)) .EnableInterfaceInterceptors(); //================= 启用 类代理拦截=== 只会拦截虚方法================== // 方式一 添加特性 [Intercept(typeof(xxx拦截器))] //builder.RegisterType().EnableClassInterceptors(); // 方式二 不需要添加 特性Intercept builder.RegisterType().InterceptedBy(typeof(LoggingInterceptor)).EnableClassInterceptors(); #endregion // 程序集注册 //builder.RegisterAssemblyTypes(Assembly.Load("Web01")) // .Where(a => a.Name.EndsWith("Services")) // .AsImplementedInterfaces() // .InstancePerLifetimeScope() // .EnableInterfaceInterceptors() // .InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor), typeof(TransactionInterceptor)); base.Load(builder); } } } ``` ##### Autofac 三种生命周期 InstancePerLifetimeScope、SingleInstance、InstancePerDependency ```csharp builder.RegisterType().As() //.EnableInterfaceInterceptors方法会动态创建一个接口代理 // .EnableClassInterceptors方法会创建一个目标类的子类代理类,这里需要注意的是只会拦截虚方法,重写方法 //-InstancePerLifetimeScope 每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用 //.AsImplementedInterfaces():注册的服务的生命周期是默认的 Transient 生命周期 //.SingleInstance():在整个应用程序生命周期中只创建一个实例,并在每次解析时重用 //.InstancePerDependency():每次解析时都创建一个新的实例 ``` InstancePerLifetimeScope: 同一个Lifetime生成的对象是同一个实例 (每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用) SingleInstance: 单例模式,每次调用,都会使用同一个实例化的对象;每次都用同一个对象; 在整个应用程序生命周期中只创建一个实例,并在每次解析时重用 InstancePerDependency: 默认模式,每次调用,都会重新实例化对象;每次请求都创建一个新的对象 每次解析时都创建一个新的实例 #### AsImplementedInterfaces() ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/15594e7a912e45bcb96df5097cd89786.png) ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6dd67d42271147d984eb9f110dba3780.png) AsImplementedInterfaces() 是以**接口方式进行注入,注入这些类的所有的公共接口作为** 服务(除了释放资源) AsImplementedInterfaces注册的服务的生命周期是默认的 **Transient** 生命周期 builder.RegisterType().AsImplementedInterfaces(); 使用时用IA,会返回一个A的实例,即将自身的实例进行注入 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/cf278e05556f4e17a4bf09a8364537da.png) 1. builder.RegisterType().As(); 接受 用 IZenServices 2. builder.RegisterType(); 接受 用 MyZenServices 3. builder.RegisterType().AsImplementedInterfaces(); 接受 用 IZenServices #### builder.RegisterAssemblyTypes 注册程序集中符合条件的类型 ```csharp Assembly assembly = Assembly.Load(assemblyName); //Assembly assembly = this.GetType().GetTypeInfo().Assembly; builder.RegisterAssemblyTypes(assembly).Where(type => !type.IsInterface && !type.IsSealed && !type.IsAbstract && type.Name.EndsWith("BLL", StringComparison.OrdinalIgnoreCase)) .AsImplementedInterfaces() .InstancePerLifetimeScope() .EnableInterfaceInterceptors() .InterceptedBy(typeof(LogInterceptor)); ``` ###### IInterceptorSelector 》》》没有没有 InterceptedBy 则需要加特性,但InterceptedBy 如果太多不利于管理,所以 IInterceptorSelector ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/8c696ce597494995908b0cd65efc1db8.png) ```csharp public class ZenLogg : IInterceptorSelector { /// /// 让我们选择使用那个IInterceptor /// /// /// /// /// /// public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors) { return new IInterceptor[] { new LoggingInterceptor(), new PerformanceInterceptor(), new TransactionInterceptor() }; } } ``` ```csharp //支持AAOP扩展--接口扩展 builder.RegisterType().As().EnableInterfaceInterceptors( new ProxyGenerationOptions() { Selector = new ZenLogg() }); ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/4bb8a1f63cc645739f82810196412307.png) ##### AOP 实现缓存 》》》简易化 ```csharp public class CusotmCacheInterceptor : IInterceptor { /// /// 定义构造函数 /// private readonly ILogger _ILogger; /// /// 初始化构造函数 /// /// public CusotmCacheInterceptor(ILogger logger) { this._ILogger = logger; } //定义字典 private static Dictionary _cacheDictionary = new Dictionary(); /// /// 切入者逻辑 /// /// public void Intercept(IInvocation invocation) { //方法之前检查缓存的结果 //定义Key string cacheKey = invocation.Method.Name; //判断当前是否有缓存结果 if (_cacheDictionary.ContainsKey(cacheKey)) { invocation.ReturnValue = _cacheDictionary[cacheKey]; } else { //执行真实的方法 invocation.Proceed(); //方法之后保存缓存的结果 _cacheDictionary[cacheKey] = invocation.ReturnValue; } } ``` [资料](https://blog.csdn.net/sD7O95O/article/details/78477440)

相关推荐
IT_10243 小时前
Spring Boot项目开发实战销售管理系统——系统设计!
大数据·spring boot·后端
ai小鬼头4 小时前
AIStarter最新版怎么卸载AI项目?一键删除操作指南(附路径设置技巧)
前端·后端·github
Touper.4 小时前
SpringBoot -- 自动配置原理
java·spring boot·后端
一只叫煤球的猫4 小时前
普通程序员,从开发到管理岗,为什么我越升职越痛苦?
前端·后端·全栈
一只鹿鹿鹿5 小时前
信息化项目验收,软件工程评审和检查表单
大数据·人工智能·后端·智慧城市·软件工程
专注VB编程开发20年5 小时前
开机自动后台运行,在Windows服务中托管ASP.NET Core
windows·后端·asp.net
程序员岳焱5 小时前
Java 与 MySQL 性能优化:MySQL全文检索查询优化实践
后端·mysql·性能优化
一只叫煤球的猫6 小时前
手撕@Transactional!别再问事务为什么失效了!Spring-tx源码全面解析!
后端·spring·面试
旷世奇才李先生6 小时前
Ruby 安装使用教程
开发语言·后端·ruby
沃夫上校9 小时前
Feign调Post接口异常:Incomplete output stream
java·后端·微服务