什么是AOP?引用百度百科:AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。实现AOP主要由两种方式,一种是编译时静态植入,优点是效率高,缺点是缺乏灵活性,.net下postsharp为代表者(这个是收费的)。另一种方式是动态代理,优缺点与前者相反,动态为目标类型创建代理,通过代理调用实现拦截。AOP能做什么,常见的用例是事务处理、日志记录等等。下面就讲讲Autofac怎么实现AOP,Autofac是一个.net下非常优秀,性能非常好的IOC容器(.net下效率最高的容器),加上AOP简直是如虎添翼。Autofac的AOP是通过Castle(也是一个容器)项目的核心部分实现的,名为Autofac.Extras.DynamicProxy,顾名思义,其实现方式为动态代理。

  使用前的准备:

    通过Nuget安装程序包 :Autofac、Autofac.Extras.DynamicProxy,安装成功之后会增加三个引用

    

  下面正式开始了!

  第一步:创建拦截器

  下面是一个简单的拦截器示例,该拦截器的功能是显示被拦截的方法名称、参数列表和返回结果

  

  /// <summary>
/// 拦截器 需要实现 IInterceptor接口 Intercept方法
/// </summary>
public class CallLogger: IInterceptor
{
TextWriter _output; public CallLogger(TextWriter output)
{
_output = output;
} /// <summary>
/// 拦截方法 打印被拦截的方法执行前的名称、参数和方法执行后的 返回结果
/// </summary>
/// <param name="invocation">包含被拦截方法的信息</param>
public void Intercept(IInvocation invocation)
{ _output.WriteLine("你正在调用方法 \"{0}\" 参数是 {1}... ",
invocation.Method.Name,
string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray())); //在被拦截的方法执行完毕后 继续执行
invocation.Proceed(); _output.WriteLine("方法执行完毕,返回结果:{0}", invocation.ReturnValue);
}
}

  第二步:注册拦截器到Autofac容器

  拦截器必须注册到Aufofac容器中,可以通过拦截器类型或者命名注入,这两种方式会让使用拦截器的方法有所不同(后面会讲到)。

  

             // 命名注入
builder.Register(c => new CallLogger(Console.Out))
.Named<IInterceptor>("log-calls"); // 类型注入
builder.Register(c => new CallLogger(Console.Out));

  第三步:启用拦截器

  启用拦截器主要有两个方法:EnableInterfaceInterceptors(),EnableClassInterceptors()。

  EnableInterfaceInterceptors方法会动态创建一个接口代理

  EnableClassInterceptors方法会创建一个目标类的子类代理类,这里需要注意的是只会拦截虚方法,重写方法

  启用拦截器示例代码:

  

            //启用类代理拦截
builder.RegisterType<Circle>().EnableClassInterceptors();
//启用接口代理拦截
builder.RegisterType<Circle>().EnableInterfaceInterceptors();

  第四步:指明要拦截的类型

  有两种方法:

    第一种:给类型加上特性Attribute

    

    第二种:在注册类型到容器的时候动态注入拦截器

    

             //动态注入拦截器CallLogger
builder.RegisterType<Circle>().InterceptedBy(typeof(CallLogger)).EnableClassInterceptors();

  第五步:测试效果了

    1.类代理拦截

    

    Circle类代码:

    

    2.接口代理拦截

    

    IShape接口代码:

    

 public interface IShape
{
/// <summary>
/// 形状的面积
/// </summary>
void Area(); }

    Circle类代码:

    

 public class Circle:IShape
{
//重写父类抽象方法
public void Area()
{
Console.WriteLine("你正在调用圆求面积的方法");
}
}

    如果有什么地方写得不对欢迎批评改正,如果有什么疑问,欢迎提问。

.NET 通过 Autofac 和 DynamicProxy 实现AOP的更多相关文章

  1. 使用Castle DynamicProxy (AOP)

    在本文中,我将引导您了解.NET环境中的面向方面编程(AOP)概念,以及如何使用Castle DynamicProxy创建和附加方面.在我们开始之前,让我快速介绍AOP和  IoC.如果您已经熟悉这些 ...

  2. 基于Autofac, Castle.DynamicProxy的动态WCF解决方案(原创)

    本方案解决了下面3个主要的问题: 1.减少配置,为了避免每次新增service都需要去修改配置文件,包括服务器端跟各个客户端的. 2.能够使用函数重载,泛型函数,以及泛型类. 3.使项目能够快速地在w ...

  3. .net core 3.1 过滤器(Filter) 与中间件与AOP面向切面 与拦截器及其应用

    Filter(过滤器) 总共有五种,Authorization Filter,Resource Filter,Exception Filter,Action Filter,Result Filter ...

  4. Asp.NetCore 中Aop的应用

    前言 其实好多项目中,做一些数据拦截.数据缓存都有Aop的概念,只是实现方式不一样:之前大家可能都会利用过滤器来实现Aop的功能,如果是Asp.NetCore的话,也可能会使用中间件: 而这种实现方式 ...

  5. 基于ef core 2.0的数据库增删改审计系统

    1.首先是建审计存储表 CREATE TABLE [dbo].[Audit] ( [Id] [uniqueidentifier] NOT NULL, [EntityName] [nvarchar](1 ...

  6. 6. abp中的拦截器

    abp拦截器基本定义 拦截器接口定义: public interface IAbpInterceptor { void Intercept(IAbpMethodInvocation invocatio ...

  7. 一个轻量级的.Net Core微服务快速开发的轮子

    前言     Adnc是一个轻量级的.Net Core微服务快速开发框架,同时也可以应用于单体架构系统的开发.框架基于JWT认证授权.集成了一系列微服务配套组件,代码简洁.易上手.学习成本低.开箱即用 ...

  8. [AOP系列]Autofac+Castle实现AOP事务

    一.前言 最近公司新项目,需要搭架构进行开发,其中需要保证事务的一致性,经过一番查找,发现很多博文都是通过Spring.Net.Unity.PostSharp.Castle Windsor这些方式实现 ...

  9. [AOP系列]Autofac+Castle实现AOP日志

    一.前言 最近公司新项目,需要搭架构进行开发,其中需要对一些日志进行输出,经过一番查找,发现很多博文都是通过Spring.Net.Unity.PostSharp.Castle Windsor这些方式实 ...

随机推荐

  1. Vue.use自定义自己的全局组件

    通常我们在vue里面使用别人开发的组件,第一步就是install,第二步在main.js里面引入,第三步Vue.use这个组件.今天我简单的也来use一个自己的组件. 这里我用的webpack-sim ...

  2. 测试开发技术:DOM中 innerHTML、innerText、outerHTML、outerText的区别

    测试开发技术:DOM中 innerHTML.innerText.outerHTML.outerText的区别   我们在做web自动化的过程中通过dom处理web页面元素,那么你就要了解innerHT ...

  3. `define、parameter、localparam三者的区别

    `define: 可以跨模块的定义,写在模块名称上面,在整个设计工程都有效.一旦'define指令被编译,其在整个编译过程中都有效.例如,通过另一个文件中的`define指令,定义的常量可以被其他文件 ...

  4. JavaScript基础学习(二)—JavaScript基本概念

    一.语法 1.区分大小写     JavaScript是一种弱类型的脚本语言.它区分大小写,变量名test与Test表示两个完全不同的变量.   2.标识符      所谓标识符就是变量.函数.属性的 ...

  5. Servlet(一)基础总结

    一.Servlet概述 1.Java Servlet是基于Java的一种技术和标准,是独立于平台和协议,服务器端的java应用程序.与Applet相比.Applet运行在客户端,而Servlet运行在 ...

  6. asp.net core 编译mvc,routing,security源代码进行本地调试

    因为各种原因,需要查看asp.net core mvc的源代码来理解运行机制等等,虽说源代码查看已经能很好的理解了.但是能够直接调试还是最直观的.所有就有了本次尝试. 因调试设置源代码调试太辍笔,所以 ...

  7. 使用纯CSS方案,解决垂直居中

    CSS是HTML元素的剪刀手,它极度的丰富了web页面的修饰.在众多CSS常见的样式需求中,有一奇葩式的存在[垂直居中],因为不管是从逻辑实现方面还是从正常需求量来讲,这都没理由让这个需求在实践过程中 ...

  8. Elasticsearch高级搜索排序( 中文+拼音+首字母+简繁转换+特殊符号过滤)

    一.先摆需求: 1.中文搜索.英文搜索.中英混搜   如:"南京东路","cafe 南京东路店" 2.全拼搜索.首字母搜索.中文+全拼.中文+首字母混搜   如 ...

  9. Js插件开发

    简易JS插件开发,本文效果是一个简单的弹出层,意在记录插件的封装Demo. 完整源码压缩包:demo.rar 效果图(如下): 插件脚本: /** * 节点配置属性方式配置参数:专业的做法是配置到,每 ...

  10. stm32中的延时函数

    //粗延时函数,微秒 void delay_nus(u16 time) { u16 i=0; while(time--) { i=10;  //自己定义 while(i--) ; } } //毫秒级的 ...