.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 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

Visual Studio 64位应用程序编译

Visual Studio的编译选项 build下的platform有X64、Any CPU和x86。X86表示只能在32位环境下运行,X64表示只能在64位环...

1945
来自专栏张善友的专栏

ASP.NET Web API: 宿主(Hosting)

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

2176
来自专栏技术博客

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

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

861
来自专栏有趣的django

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

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

47111
来自专栏逸鹏说道

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

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

1113
来自专栏Jackie技术随笔

TCP回射客户-服务器程序

创建一个TCP套接口,用通配地址(INADDR_ANY)和unp.h中定义的众所周知端口(SERV_PORT),端口号为9877。

2155
来自专栏Hongten

python开发_getpass_获取登录名

我们有时候需要获取到计算机的登录名,这时候,就可以使用python中的getpass模块了

752
来自专栏小灰灰

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

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

1.1K8
来自专栏晓晨的专栏

ASP.NET Core 依赖注入(DI)简介

3864
来自专栏Jackson0714

C#多线程之旅(1)——介绍和基本概念

2759

扫码关注云+社区