天天看點

C#進階系列——AOP?AOP!

前言:今天大閱兵,可是苦逼的部落客還得坐在電腦前寫部落格,為了弄清楚AOP,部落客也是拼了。這篇打算寫寫AOP,說起AOP,其實部落客接觸這個概念也才幾個月,了解後才知道,原來之前自己寫的好多代碼原理就是基于AOP的,比如MVC的過濾器Filter,它裡面的異常捕捉可以通過FilterAttribute,IExceptionFilter去處理,這兩個對象的處理機制内部原理應該就是AOP,隻不過之前沒有這個概念罷了。

老規矩,還是先看官方解釋:AOP(Aspect-Oriented Programming,面向切面的程式設計),它是可以通過預編譯方式和運作期動态代理實作在不修改源代碼的情況下給程式動态統一添加功能的一種技術。它是一種新的方法論,它是對傳統OOP程式設計的一種補充。OOP是關注将需求功能劃分為不同的并且相對獨立,封裝良好的類,并讓它們有着屬于自己的行為,依靠繼承和多态等來定義彼此的關系;AOP是希望能夠将通用需求功能從不相關的類當中分離出來,能夠使得很多類共享一個行為,一旦發生變化,不必修改很多類,而隻需要修改這個行為即可。AOP是使用切面(aspect)将橫切關注點子產品化,OOP是使用類将狀态和行為子產品化。在OOP的世界中,程式都是通過類和接口組織的,使用它們實作程式的核心業務邏輯是十分合适。但是對于實作橫切關注點(跨越應用程式多個子產品的功能需求)則十分吃力,比如日志記錄,權限驗證,異常攔截等。

部落客的了解:AOP就是将公用功能提取出來,如果以後公用功能的需求發生變化,隻需要改動公用的子產品的代碼即可,多個調用的地方則不需要改動。所謂面向切面,就是隻關注通用功能,而不關注業務邏輯。實作方式一般是通過攔截。比如,我們随便一個Web項目基本都有的權限驗證功能,進入每個頁面前都會校驗目前登入使用者是否有權限檢視該界面,我們不可能說在每個頁面的初始化方法裡面都去寫這段驗證的代碼,這個時候我們的AOP就派上用場了,AOP的機制是預先定義一組特性,使它具有攔截方法的功能,可以讓你在執行方法之前和之後做你想做的業務,而我們使用的時候隻需要的對應的方法或者類定義上面加上某一個特性就好了。

部落客覺得它的優勢主要表現在:

1、将通用功能從業務邏輯中抽離出來,可以省略大量重複代碼,有利于代碼的操作和維護。

2、在軟體設計時,抽出通用功能(切面),有利于軟體設計的子產品化,降低軟體架構的複雜度。也就是說通用的功能都是一個單獨的子產品,在項目的主業務裡面是看不到這些通用功能的設計代碼的。

為了說明AOP的工作原理,部落客打算先從一個簡單的例子開始,通過靜态攔截的方式來了解AOP是如何工作的。

C#進階系列——AOP?AOP!
C#進階系列——AOP?AOP!

調用代碼:

C#進階系列——AOP?AOP!
C#進階系列——AOP?AOP!

得到結果:

C#進階系列——AOP?AOP!

上面我們模拟訂單送出的例子,在送出一個訂單前,我們需要做很多的準備工作,比如資料有效性校驗等;訂單送出完成之後,我們還需要做日志記錄等。上面的代碼很簡單,沒有任何複雜的邏輯,從上面的代碼可以看出,我們通過靜态植入的方式手動在執行方法前和執行方法後讓它做一些我們需要的功能。AOP的實作原理應該也是如此,隻不過它幫助我們做了方法攔截,幫我們省去了大量重複代碼,我們要做的僅僅是寫好攔截前和攔截後需要處理的邏輯。

了解了靜态攔截的例子,你是否對AOP有一個初步的認識了呢。下面我們就來到底AOP該如何使用。按照園子裡面很多牛人的說法,AOP的實作方式大緻可以分為兩類:動态代理和IL 編織兩種方式。部落客也不打算照本宣科,分别拿Demo來說話吧。下面就以兩種方式各選一個代表架構來說明。

動态代理方式,部落客就以微軟企業庫(MS Enterprise Library)裡面的PIAB(Policy Injection Application Block)架構來作說明。

首先需要下載下傳以下幾個dll,然後添加它們的引用。

C#進階系列——AOP?AOP!

然後定義對應的Handler

C#進階系列——AOP?AOP!
C#進階系列——AOP?AOP!

最後我們來看調用的代碼:

C#進階系列——AOP?AOP!
C#進階系列——AOP?AOP!

得到結果如下:

C#進階系列——AOP?AOP!

我們來看執行Test()方法和Test2()方法時候的順序。

C#進階系列——AOP?AOP!

由于Test()和Test2()方法上面加了LogHander特性,這個特性裡面定義了AOP的Handler,在執行Test和Test2方法之前和之後都會進入Invoke()方法裡面。其實這就是AOP的意義所在,将切面的通用功能在統一的地方處理,在主要邏輯裡面直接用過特性使用即可。

靜态織入的方式部落客打算使用PostSharp來說明,一來這個使用起來簡單,二來項目中用過這種方式。

Postsharp從2.0版本就開始收費了。為了說明AOP的功能,部落客下載下傳了一個免費版本的安裝包,使用PostSharp與其它架構不太一樣的是一定要下載下傳安裝包安裝,隻引用類庫是不行的,因為上文說過,AOP架構需要為編譯器或運作時添加擴充。使用步驟如下:

(1)下載下傳Postsharp安裝包,安裝。

(2)在需要使用AOP的項目中添加PostSharp.dll 這個dll的引用。

(3)定義攔截的方法:

C#進階系列——AOP?AOP!
C#進階系列——AOP?AOP!

注意這裡的TestAop這個類必須要是可序列化的,是以要加上[Serializable]特性

(4)在需要攔截功能的地方使用。

在類上面加特性攔截,此類下面的所有的方法都會具有攔截功能。

C#進階系列——AOP?AOP!
C#進階系列——AOP?AOP!

方法上面加特性攔截,隻會攔截此方法。

C#進階系列——AOP?AOP!
C#進階系列——AOP?AOP!

有沒有感覺很簡單,很強大,其實這一簡單應用,解決我們常見的日志、異常、權限驗證等功能簡直太小菜一碟了。當然Postsharp可能還有許多更加進階的功能,有興趣可以深究下。

C#進階系列——AOP?AOP!
C#進階系列——AOP?AOP!

在controller裡面使用該特性:

C#進階系列——AOP?AOP!
C#進階系列——AOP?AOP!

調試可知,在執行GetEditModel(string strType)方法之前,會先執行OnActionExecuting()方法,GetEditModel(string strType)之後,又會執行OnActionExecuted()方法。這在我們MVC裡面權限驗證、錯誤頁導向、日志記錄等常用功能都可以友善解決。

本文轉自懶得安分部落格園部落格,原文連結:http://www.cnblogs.com/landeanfen/p/4782370.html,如需轉載請自行聯系原作者