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

news2024/12/1 3:20:41

资料
在这里插入图片描述

core 实现autofac

》》》 安装 如下工具包
在这里插入图片描述

安装之后 如出现 这种
在这里插入图片描述

》》》编写 AOP类

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");
            }

        }
    }
}

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(拦截器))] 修饰接口实现的类,则只有此类的方法会拦截。

在这里插入图片描述

在这里插入图片描述


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}"); ;
        }
    }
}

using Autofac;
using Autofac.Extras.DynamicProxy;
using Web01.AOP;

namespace Web01.Comm
{
    /// <summary>
    /// Moudle 是Autofac命名空间下面的 
    /// </summary>
    public class AutofacMoudleManager:Module
    {
        /// <summary>
        /// 重写Autofac管道Load 方法,load方法里面是注册注入的
        /// </summary>
        /// <param name="builder"></param>
        protected override void Load(ContainerBuilder builder)
        {
            #region   注册 AOP
            //注册日志记录拦截器
            builder.RegisterType<LoggingInterceptor>();
            //注册性能拦截器
            builder.RegisterType<PerformanceInterceptor>();
            //注册事务管理器拦截器
            builder.RegisterType<TransactionInterceptor>();
            #endregion
            //builder.RegisterType<MyAresServices>().As<IAresServices>();
            builder.RegisterType<MyZenServices>().As<IZenServices>().InstancePerDependency().EnableInterfaceInterceptors(); 
            builder.RegisterType<MyAresServices>().As<IAresServices>().InstancePerDependency().EnableInterfaceInterceptors(); 

            //    .EnableInterfaceInterceptors() 
            //     .AsImplementedInterfaces()
            //    .InstancePerLifetimeScope()
            //    .EnableInterfaceInterceptors()
            //    .InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor), typeof(TransactionInterceptor));
            ;
            //builder.RegisterType<MyZenServices>().As<IZenServices>();
            //通.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);
        }
    }
}

在这里插入图片描述

 builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
             .ConfigureContainer<ContainerBuilder>(containerBuilder =>
             {
                 containerBuilder.RegisterModule<AutofacMoudleManager>();
             });

在这里插入图片描述

忽略拦截

声明一个 特性 ,
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

 if (invocation.Method.IsDefined(typeof(NeverInterceptAttribute), true))
 {
     Console.WriteLine("=======没有被拦截==========");
     invocation.Proceed();
     return;
 }

源码

接口代理 类代理

在这里插入图片描述

using Autofac;
using Autofac.Extras.DynamicProxy;
using WebApplication2.AOP;

namespace WebApplication2.Coms
{
    public class AutofacMoudleManager:Module
    {
        /// <summary>
        /// 重写Autofac管道Load 方法,load方法里面是注册注入的
        /// </summary>
        /// <param name="builder"></param>
        protected override void Load(ContainerBuilder builder)
        {
            #region 注册 AOP  把拦截器注册到 autofac 容器中
            //注册日志记录拦截器
            //builder.RegisterType<LoggingInterceptor>();
            // 命名注入
            //builder.Register<LoggingInterceptor>(c => new LoggingInterceptor()).Named<IInterceptor>("log-record");
            // 类型注入
            //builder.Register<LoggingInterceptor>(c=>new LoggingInterceptor());
            builder.RegisterType<LoggingInterceptor>();
            //builder.RegisterType(typeof(LoggingInterceptor));
            //注册性能拦截器
            builder.RegisterType<PerformanceInterceptor>();
            //注册事务管理器拦截器
            builder.RegisterType<TransactionInterceptor>();
            #endregion
            #region 注册服务           
            builder.RegisterType<MyZenServices>().As<IZenServices>();
            // EnableInterfaceInterceptors方法会动态创建一个接口代理
            // EnableClassInterceptors方法会创建一个目标类的子类代理类,这里需要注意的是只会拦截虚方法,重写方法
            //-InstancePerLifetimeScope  每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用
            //.AsImplementedInterfaces():注册的服务的生命周期是默认的 Transient 生命周期
            //.SingleInstance():在整个应用程序生命周期中只创建一个实例,并在每次解析时重用
            //.InstancePerDependency():每次解析时都创建一个新的实例
            // 命名注册
            //builder.RegisterType<MyAresServices>().Named<IAresServices>(typeof(MyAresServices).Name).EnableClassInterceptors();
  


            //=================启用接口代理拦截====================
             //方式一:需要在接口、实现的类   添加特性   [Intercept(typeof(xxx拦截器))] 
            ///比如   [Intercept(typeof(LoggingInterceptor))]
            /// 接口加 Intercept 特性,实现接口的类  全部生效
            /// 实现类 加  Intercept 特性   ,只有此类  生效
            //builder.RegisterType<MyAresServices>().As<IAresServices>()          
            // .EnableInterfaceInterceptors();

            // //方式二:在 注册服务 类型到容器的时候动态注入拦截器(去掉接口、实现的类型上的特性 Intercept)  不要添加特性Intercept
            // InterceptedBy  支持多个拦截器
            builder.RegisterType<MyAresServices>().As<IAresServices>()
                .InterceptedBy(typeof(LoggingInterceptor), typeof(PerformanceInterceptor))
                .EnableInterfaceInterceptors();

            //================= 启用 类代理拦截===  只会拦截虚方法==================
            //  方式一   添加特性   [Intercept(typeof(xxx拦截器))] 
            //builder.RegisterType<Student>().EnableClassInterceptors();
            //  方式二  不需要添加  特性Intercept  
            builder.RegisterType<Student>().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
 builder.RegisterType<MyZenServices>().As<IZenServices>()
            //.EnableInterfaceInterceptors方法会动态创建一个接口代理
            // .EnableClassInterceptors方法会创建一个目标类的子类代理类,这里需要注意的是只会拦截虚方法,重写方法
            //-InstancePerLifetimeScope  每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用
            //.AsImplementedInterfaces():注册的服务的生命周期是默认的 Transient 生命周期
            //.SingleInstance():在整个应用程序生命周期中只创建一个实例,并在每次解析时重用
            //.InstancePerDependency():每次解析时都创建一个新的实例

InstancePerLifetimeScope:
同一个Lifetime生成的对象是同一个实例 (每个请求(即每个 HTTP 请求)创建一个实例,并在整个请求期间重用)

SingleInstance:
单例模式,每次调用,都会使用同一个实例化的对象;每次都用同一个对象;
在整个应用程序生命周期中只创建一个实例,并在每次解析时重用

InstancePerDependency:
默认模式,每次调用,都会重新实例化对象;每次请求都创建一个新的对象
每次解析时都创建一个新的实例

AsImplementedInterfaces()

在这里插入图片描述
在这里插入图片描述

AsImplementedInterfaces() 是以接口方式进行注入,注入这些类的所有的公共接口作为服务(除了释放资源)
AsImplementedInterfaces注册的服务的生命周期是默认的 Transient 生命周期

builder.RegisterType().AsImplementedInterfaces(); 使用时用IA,会返回一个A的实例,即将自身的实例进行注入

在这里插入图片描述

  1.  builder.RegisterType<MyZenServices>().As<IZenServices>();   				   接受  用  IZenServices
  2.  builder.RegisterType<MyZenServices>();                                   					   接受  用  MyZenServices
  3.  builder.RegisterType<MyZenServices>().AsImplementedInterfaces();			接受  用  IZenServices

builder.RegisterAssemblyTypes 注册程序集中符合条件的类型

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
在这里插入图片描述

public class ZenLogg : IInterceptorSelector
{
    /// <summary>
    /// 让我们选择使用那个IInterceptor
    /// </summary>
    /// <param name="type"></param>
    /// <param name="method"></param>
    /// <param name="interceptors"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors)
    {
        return new IInterceptor[] {
            new LoggingInterceptor(),
            new PerformanceInterceptor(),
            new TransactionInterceptor()
        };
    }
}
 //支持AAOP扩展--接口扩展
 builder.RegisterType<MyAresServices>().As<IAresServices>().EnableInterfaceInterceptors(
     new ProxyGenerationOptions()
     {
         Selector = new ZenLogg()
     });

在这里插入图片描述

AOP 实现缓存

》》》简易化

 public class CusotmCacheInterceptor : IInterceptor
    {
        /// <summary>
        /// 定义构造函数
        /// </summary>
        private readonly ILogger<CusotmCacheInterceptor> _ILogger;
        /// <summary>
        /// 初始化构造函数
        /// </summary>
        /// <param name="logger"></param>
        public CusotmCacheInterceptor(ILogger<CusotmCacheInterceptor> logger)
        {
            this._ILogger = logger;
        }
        //定义字典
        private static Dictionary<string, object> _cacheDictionary = new Dictionary<string, object>();
        /// <summary>
        /// 切入者逻辑
        /// </summary>
        /// <param name="invocation"></param>
        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;
            }
        }
    

资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2250838.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习】各种卷积—卷积、反卷积、空洞卷积、可分离卷积、分组卷积

在全连接神经网络中&#xff0c;每个神经元都和上一层的所有神经元彼此连接&#xff0c;这会导致网络的参数量非常大&#xff0c;难以实现复杂数据的处理。为了改善这种情况&#xff0c;卷积神经网络应运而生。 一、卷积 在信号处理中&#xff0c;卷积被定义为一个函数经过翻转…

VOLO实战:使用VOLO实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…

GPU 服务器厂家:怎样铸就卓越 AI 算力?

文章来源于百家号&#xff1a;GPU服务器厂家 今天咱来聊聊 GPU 服务器厂家那些事儿&#xff0c;而这其中衡量 AI 算力的因素可是关键所在哦。 先讲讲计算速度这一块。咱都知道 AI 那复杂的活儿&#xff0c;像训练超厉害的图像识别模型&#xff0c;得处理海量图像数据&#x…

DroneCAN 最新开发进展,Andrew在Ardupilot开发者大会2024的演讲

本文是Andrew演讲的中文翻译&#xff0c;你可以直接观看视频了解演讲的全部内容&#xff0c;此演讲视频的中文版本已经发布在Ardupilot社区的Blog板块&#xff0c;你可以在 Arudpilot官网&#xff08;https://ardupilot.org) 获取该视频&#xff1a; 你也可以直接通过Bilibili链…

USB Type-C一线通扩展屏:多场景应用,重塑高效办公与极致娱乐体验

在追求高效与便捷的时代&#xff0c;启明智显USB Type-C一线通扩展屏方案正以其独特的优势&#xff0c;成为众多职场人士、娱乐爱好者和游戏玩家的首选。这款扩展屏不仅具备卓越的性能和广泛的兼容性&#xff0c;更能在多个应用场景中发挥出其独特的价值。 USB2.0显卡&#xff…

Android 混淆问题

我的安卓混淆只需要在gradle里面开启就行了。 buildTypes {release {minifyEnabled trueshrinkResources truezipAlignEnabled trueproguardFiles getDefaultProguardFile(proguard-android-optimize.txt), proguard-rules.pro}} minifyEnabled true 这个就是开启方法&#xf…

《硬件架构的艺术》笔记(九):电磁兼容性能设计指南

简介 电子线路易于接收来自其他发射器的辐射信号&#xff0c;这些EMI&#xff08;电磁干扰&#xff09;使得设备内毗邻的元件不能同时工作。这就有必要进行电磁兼容设计以避免系统内有害的电磁干扰。 确保设备不产生多余的辐射&#xff0c;设备也不易受到射频辐射的干扰&…

MR30分布式 IO 模块在冷却水泵系统中的卓越应用

在当今各类工业生产以及大型设施运行的场景中&#xff0c;冷却水泵系统起着至关重要的作用&#xff0c;它犹如保障整个运转体系顺畅运行的 “血液循环系统”&#xff0c;维持着设备适宜的温度环境&#xff0c;确保其稳定、高效地工作。而随着科技的不断发展&#xff0c;明达技术…

【数据分析】布朗运动(维纳过程)

文章目录 一、概述二、数学布朗运动2.1 数学定义2.2 布朗运动的数学模型2.21 标准布朗运动2.22 布朗运动的路径2.23 布朗运动的方程 三、布朗运动在金融学中的应用四、数学构造&#xff08;以傅里叶级数为例&#xff09;4.1 傅里叶级数的基本思想4.2 构造布朗运动 一、概述 布…

3.22【机器学习】决策树作业代码实现

4.1由于决策树只在样本同属于一类或者所有特征值都用完或缺失时生成叶节点&#xff0c;同一节点的样本&#xff0c;在路径上的特征值都相同&#xff0c;而训练集中又没有冲突数据&#xff0c;所以必定存在训练误差为0的决策树 4.2使用最小训练误差会导致过拟合&#xff0c;使得…

数字IC后端实现之PR工具中如何避免出现一倍filler的缝隙?

在数字IC后端实现中&#xff0c;由于有的工艺foundary不提供Filler1&#xff0c;所以PR工具Innovus和ICC2在做标准单元摆放时需要避免出现两个标准单元之间的缝隙间距是Filler1。为了实现这个目的&#xff0c;我们需要给PR工具施加一些特殊的placement constraint&#xff08;典…

群控系统服务端开发模式-应用开发-前端短信配置开发

一、添加视图 在根目录下src文件夹下views文件夹下param文件夹下sms文件夹下&#xff0c;新建index.vue&#xff0c;代码如下 <template><div class"app-container"><div class"filter-container" style"float:left;"><el…

111.有效单词

class Solution {public boolean isValid(String word) {if(word.length()<3){return false;}int countV0,countC0;//分别统计原音和辅音for(int i0;i<word.length();i){if(Character.isLetterOrDigit(word.charAt(i))){if(word.charAt(i)a||word.charAt(i)e||word.charA…

python图像彩色数字化

效果展示&#xff1a; 目录结构&#xff1a; alphabets.py GENERAL {"simple": "%#*-:. ","complex": "$B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_~<>i!lI;:,\"^. " } # Full list could be found here…

欧科云链研究院:比特币还能“燃”多久?

出品&#xff5c; OKG Research 作者&#xff5c;Hedy Bi 本周二&#xff0c;隔夜“特朗普交易” 的逆转趋势波及到比特币市场。比特币价格一度冲高至约99,000美元后迅速回落至93,000美元以下&#xff0c;最大跌幅超6%。这是由于有关以色列和黎巴嫩有望达成停火协议的传闻引发…

Unity之一键创建自定义Package包

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之一键创建自定义Package包 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&#xff01; …

E2、UML类图顺序图状态图实训

一、实验目的 在面向对象的设计里面&#xff0c;可维护性复用都是以面向对象设计原则为基础的&#xff0c;这些设计原则首先都是复用的原则&#xff0c;遵循这些设计原则可以有效地提高系统的复用性&#xff0c;同时提高系统的可维护性。在掌握面向对象七个设计原则基础上&…

【Java基础入门篇】一、变量、数据类型和运算符

Java基础入门篇 一、变量、数据类型和运算符 1.1 变量 计算机中的数据表示方式是&#xff1a;“二进制(0/1)”&#xff0c;但是同时也可以兼容其他进制&#xff0c;例如八进制、十进制、十六进制等。 Java变量的本质是&#xff1a;存储在固定空间的内容&#xff0c;变量名是…

前端学习笔记之文件下载(1.0)

因为要用到这样一个场景&#xff0c;需要下载系统的使用教程&#xff0c;所以在前端项目中就提供了一个能够下载系统教程的一个按钮&#xff0c;供使用者进行下载。 所以就试着写一下这个功能&#xff0c;以一个demo的形式进行演示&#xff0c;在学习的过程中也发现了中文路径…

【力扣】387.字符串中的第一个唯一字符

问题描述 思路解析 对于这种个数有限的问题&#xff0c;我的第一想法是使用桶排序来解决因为s中只有小写英文单词&#xff0c;所以我只需要一个26个单位的数组就好了通过 charAt() 来提取单个字符&#xff0c;然后通过 -‘a’ 来将其映射到 0~25&#xff0c;不然数组长度就被超…