C#使用KingAOP實現AOP面向切面程式設計
AOP面向切面程式設計(Aspect Oriented Programming),是通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。
實現AOP主要由兩種方式,一種是編譯時靜態植入,優點是效率高,缺點是缺乏靈活性,.net下PostSharp為代表者(這個是收費的)。
另一種方式是動態代理,優缺點與前者相反,動態為目標型別建立代理,通過代理呼叫實現攔截。
Spring框架用的核心技術就是AOP,是函數語言程式設計的一種衍生範型。利用AOP的好處就是可以對業務邏輯進行隔離,降低耦合度,提高程式的可重用性,同時提高了開發的效率。
AOP在我理解來說就是一種程式設計思想和架構設計,AOP是OOP面向物件程式設計的延續,是軟體開發中的一個熱點。AOP的簡稱叫”面向切面“程式設計,即在現有的程式碼裡橫向的切分開來進行相應處理,比如說MVC裡的刷選器(過濾器)。
AOP主要功能是將系統中非核心的公共業務提取出來,進行單獨處理。比如日誌記錄、效能統計、安全控制、事務處理、異常處理等等。
AOP主要意圖是將日誌記錄,效能統計,安全控制,事務處理,異常處理等程式碼從業務邏輯程式碼中劃分出來,通過對這些行為的分離,我們希望可以將它們獨立到非指導業務邏輯的方法中,進而改變這些行為的時候不影響業務邏輯的程式碼。
下面介紹一些.NET相關的AOP框架
1.PostSharp(編譯時靜態植入)是最有名且使用率較高的一個,但是在Nuget上的版本是需要付費的(2.0)以上都要付費。
2.Spring.Net 用於解決企業應用開發複雜性的一種容器框架,它實現了控制反轉IOC和依賴注入DI,通俗解釋就是通過spring.net框架的容器來建立物件實體,而不是通過程式設計師new出來,
降低程式對服務類的依賴性,提高軟體的可擴充套件性。只要在spring.net的相應xml中配置節點,建立容器上下文後再通過配置獲取物件就可以。
3.Autofac是一個.net下非常優秀,效能非常好的IOC容器(.net下效率最高的容器),加上AOP簡直是如虎添翼。Autofac的AOP是通過Castle(也是一個容器)專案的核心部分實現的,名為Autofac.Extras.DynamicProxy,
顧名思義其實現方式為動態代理。
4.Castle.Core本質是建立繼承原來類的代理類,重寫虛方法實現AOP功能。
5.KingAOP開源框架KingAOP是基於動態型別進行操作和繫結的。
個人推薦使用Castle.Core 或者KingAOP
下面介紹一個比較精簡的AOP框架:KingAOP使用方式比較簡單,如下順序:
1、在Nuget上搜索KingAOP,如圖:
或者通過命令安裝:
Install-Package KingAOP
2、建立一個刷選器類(切面處理類),繼承OnMethodBoundaryAspect,並重寫相關的事件,如下程式碼:
/// <summary> /// 建立一個刷選器類(切面處理類) /// </summary> public class AopFilter : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionArgs args) { Console.WriteLine("call-------->AopFilter------>OnEntry"); base.OnEntry(args); } public override void OnException(MethodExecutionArgs args) { Console.WriteLine("call-------->AopFilter------>OnException"); base.OnException(args); } public override void OnSuccess(MethodExecutionArgs args) { Console.WriteLine("call-------->AopFilter------>OnSuccess"); base.OnSuccess(args); } public override void OnExit(MethodExecutionArgs args) { Console.WriteLine("call-------->AopFilter------>OnExit"); base.OnExit(args); } }
3、建立一個類,該類的方法註冊上面新建的刷選器,如下程式碼:
/// <summary> /// 該類需要繼承IDynamicMetaObjectProvider,因為KingAOP是基於動態型別進行操作和繫結的,如不繼承是不會進入到刷選器中的相應事件裡 /// </summary> public class SimonDemo : IDynamicMetaObjectProvider { public SimonDemo() { Console.WriteLine(" Call 'SimonDemo類' - 'Constructor(建構函式)'"); } [AopFilter] public void Operate() { Console.WriteLine("Call 'SimonDemo類' - 'Operate方法' "); } /// <summary> /// 該類必須實現IDynamicMetaObjectProvider的GetMetaObject方法 /// </summary> /// <param name="parameter"></param> /// <returns></returns> public DynamicMetaObject GetMetaObject(Expression parameter) { return new AspectWeaver(parameter, this); } }
上面的SimonDemo類需要繼承IDynamicMetaObjectProvider,因為KingAOP是基於動態型別進行操作和繫結的,如不繼承是不會進入到刷選器中的相應事件裡。
該類必須實現IDynamicMetaObjectProvider的GetMetaObject方法,同時在需要切面的方法上用屬性[AopFilter]進行標註,
同時,刷選器屬性是限制了只能對應方法,且不包含建構函式;
4、接下來就是測試程式碼,如下
static void Main(string[] args) { //簡單例子 Console.WriteLine("Call Main .."); //注意:如果需要用KingAop進行橫向切面則必須在例項化被切面的類時用動態型別dynamic接收 dynamic simon = new SimonDemo(); simon.Operate(); Console.WriteLine("exit Main .."); Console.Read(); }
上面的程式碼執行後是這個樣子的,如下圖:
仔細看程式碼SimonDemo是以動態型別 dynamic來接收的,我們把程式碼改成SimonDemo simon = new SimonDemo();後執行會怎麼樣?如下圖:
實踐後發現,如果需要用KingAop進行橫向切面則必須在例項化被切面的類時用動態型別dynamic接收。
整體而言,這個框架還是挺簡單的
來源--https://www.cnblogs.com/li150dan/p/9989460.html