.NET 通过 Autofac 和 DynamicProxy 实现AOP

  什么是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,安装成功之后会增加三个引用

  下面正式开始了!

  第一步:创建拦截器

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

 1  /// <summary>
 2     /// 拦截器 需要实现 IInterceptor接口 Intercept方法
 3     /// </summary>
 4     public class CallLogger: IInterceptor
 5     {
 6         TextWriter _output;
 7 
 8         public CallLogger(TextWriter output)
 9         {
10             _output = output;
11         }
12 
13         /// <summary>
14         /// 拦截方法 打印被拦截的方法执行前的名称、参数和方法执行后的 返回结果
15         /// </summary>
16         /// <param name="invocation">包含被拦截方法的信息</param>
17         public void Intercept(IInvocation invocation)
18         {
19             
20             _output.WriteLine("你正在调用方法 \"{0}\"  参数是 {1}... ",
21               invocation.Method.Name,
22               string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
23 
24             //在被拦截的方法执行完毕后 继续执行
25             invocation.Proceed();
26 
27             _output.WriteLine("方法执行完毕,返回结果:{0}", invocation.ReturnValue);
28         }
29     }

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

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

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

  第三步:启用拦截器

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

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

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

  启用拦截器示例代码:

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

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

  有两种方法:

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

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

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

  第五步:测试效果了

    1.类代理拦截

    Circle类代码:

     2.接口代理拦截

     IShape接口代码:

1 public interface IShape
2     {
3         /// <summary>
4         /// 形状的面积
5         /// </summary>
6         void Area();
7 
8     }

    Circle类代码:

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

ASP.NET Web API: 宿主(Hosting)

ASP.NET Web API 处理架构中介绍了ASP.NET Web API主要有三层组成:宿主(hosting),消息处理管道(message handle...

2316
来自专栏技术博客

设计模式之四(抽象工厂模式第一回合)

首先关于抽象工厂模式的学习,我们需要慢慢的,由浅入深的进入。不能单刀直入,否则可能达不到预期学明白的目标。

1041
来自专栏应用案例

VBA创建Access数据库的4种方法

Excel由于本身的局限性,存储数据量过大的时候,往往会导致工作簿假死无反应,电脑卡顿等情况。那么,将数据存取到Access数据库中就是一种好的解决方法。今天,...

47710
来自专栏大内老A

在一个空ASP.NET Web项目上创建一个ASP.NET Web API 2.0应用

由于ASP.NET Web API具有与ASP.NET MVC类似的编程方式,再加上目前市面上专门介绍ASP.NET Web API 的书籍少之又少(我们看到的...

47910
来自专栏小灰灰

Java实现几种简单的重试机制

背景 当业务执行失败之后,进行重试是一个非常常见的场景,那么如何在业务代码中优雅的实现重试机制呢? 设计 我们的目标是实现一个优雅的重试机制,那么先来看下怎么...

2K8
来自专栏散尽浮华

linux运维中的命令梳理(二)

回想起来,从事linux运维工作已近5年之久了,日常工作中会用到很多常规命令,之前简单罗列了一些命令:http://www.cnblogs.com/keving...

2338
来自专栏扎心了老铁

python语言中的AOP利器:装饰器

一、前言 面向切面编程(AOP)是一种编程思想,与OOP并不矛盾,只是它们的关注点相同。面向对象的目的在于抽象和管理,而面向切面的目的在于解耦和复用。 举两个大...

3678
来自专栏逸鹏说道

Python3 与 C# 并发编程之~ 进程篇下

看看 connection.Pipe方法的定义部分,是不是双向通信就看你是否设置 duplex=True

1443
来自专栏有趣的django

Django rest framework源码分析(1)----认证

一、基础 1.1.安装 两种方式: github pip直接安装 pip install django-rest-framework 1.2.需要先了解的一...

53611
来自专栏程序员互动联盟

【专业技术第五讲】动态链接库及其用法

存在的疑惑: 动态链接库到底如何来使用?特别是windows上面 解决方案: 本篇我们讲Windows上的动态链接库(Dynamic Link Library ...

3087

扫码关注云+社区