天天看點

.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,安裝成功之後會增加三個引用

    

.NET 通過 Autofac 和 DynamicProxy 實作AOP

  下面正式開始了!

  第一步:建立攔截器

  下面是一個簡單的攔截器示例,該攔截器的功能是顯示被攔截的方法名稱、參數清單和傳回結果

  

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

.NET 通過 Autofac 和 DynamicProxy 實作AOP

    第二種:在注冊類型到容器的時候動态注入攔截器

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

  第五步:測試效果了

    1.類代理攔截

.NET 通過 Autofac 和 DynamicProxy 實作AOP

    Circle類代碼:

.NET 通過 Autofac 和 DynamicProxy 實作AOP

     2.接口代理攔截

.NET 通過 Autofac 和 DynamicProxy 實作AOP

     IShape接口代碼:

1 public interface IShape
2     {
3         /// <summary>
4         /// 形狀的面積
5         /// </summary>
6         void Area();
7 
8     }      
1 public class Circle:IShape
2     {
3         //重寫父類抽象方法
4         public void Area()
5         {
6             Console.WriteLine("你正在調用圓求面積的方法");
7         }
8     }      

    如果有什麼地方寫得不對歡迎批評改正,如果有什麼疑問,歡迎提問。

目前學習.NET Core 最好的教程 .NET Core 官方教程 ASP.NET Core 官方教程

.NET Core 交流群:923036995  歡迎加群交流

如果您認為這篇文章還不錯或者有所收獲,您可以點選右下角的【推薦】支援,或請我喝杯咖啡【贊賞】,這将是我繼續寫作,分享的最大動力!

作者:曉晨Master(李志強)

聲明:原創部落格請在轉載時保留原文連結或者在文章開頭加上本人部落格位址,如發現錯誤,歡迎批評指正。凡是轉載于本人的文章,不能設定打賞功能,如有特殊需求請與本人聯系!