1. 程式人生 > >Autofac的AOP面向切面程式設計研究

Autofac的AOP面向切面程式設計研究

 

什麼是AOP:

我的理解是 把系統性的程式設計工作封裝起來 =》我給這個取個名字叫 “Aspect”,然後通過AOP技術把它切進我們的業務邏輯程式碼 =》 “業務“

這樣的好處:

“Aspect” 和 “業務” 相互獨立,既可以讓“業務” 用到了 “Aspect” 又讓2者互相獨立不耦合,多個“業務”也能複用 同一份“Aspect”

舉一個最實用的例子 Transaction 事物

我們經常會在業務程式碼上使用Transaction事物,比如使用TransactionScope:

下面的測試程式碼用到了我在維護的一個開源ORM框架

https://github.com/yuzd/AntData.ORM

示例業務程式碼:

上面的程式碼 就是 插入一個學校到db 然後拿到主鍵 賦值給 person 再insert到db。 在同一個事物裡面 要麼school 和person 同時插入db 要麼都失敗。

實際業務程式碼肯定比這個要複雜的多了,比如多個方法在一個事物裡面等我這裡就舉最簡單的例子。

那麼如果每段業務邏輯都這麼寫的話 會造成重複性程式碼很多,下面我們就嘗試用AOP面向對切的思想去優化

思考怎樣的方式才是我想要的

示例程式碼:

如上圖: 我在需要用到事物的方法上面打了一個 EnableTransactionScope 標籤 這樣遇到業務方法需要用事物包裹的話 都可以打上這個標籤

假如要實現這樣的話 得實現以下幾點:

  1. 我需要代理類,因為只有代理類才能給業務程式碼做些手腳(織入我們想要的邏輯包裹)
  2. 我需要一個DI容器,因為將例項的生成交給DI容器了會很方面的生成代理類
  3. 我希望只是打打標籤就能實現以上這些,這樣視覺化最好,也方便

朝著目標去實現它 Just Do It

1. 使用Autofac 這款DI容器 配合 Autofac.Extras.DynamicProxy 庫

這2個庫都是autofac旗下現成的開源產品,有了這2個庫 就滿足我上面提到的需求1和需求2

第3點看來得親自動手了

噹噹噹噹~~

Autofac.Annotation元件誕生

這個元件是我維護的一個開源的autofac擴充套件庫,用來實現打打標籤 就能實現一些複雜的配置!

2. 如何使用 Autofac.Annotation 幫助實現AOP面向切面程式設計

先簡單來個示例程式碼:

更多示例請查閱:https://github.com/yuzd/Autofac.Annotation

3. 使用織入來實現TransactionScope切面

 

新建一個class如下繼承PointcutAttribute 並實現方法: 注意:由於是非同步環境 必須使用 new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)

只需要在在需要事物包裹的方法上打上這個標籤 [EnableTransactionScope] 如下圖:

點我檢視以上程式碼

總結

使用Autofac.Annotation元件可以很方便的讓我們在業務程式碼中使用AOP切面,可以自定義實現切入的位置(前置,後置,還是Arround等)

參考上面程式碼,

  • 打了Componet標籤就把類注入到autofac容器了
  • 打了Aspect標籤就代表該類需要autofac幫我生成代理類
  • 方法上面打了指定的標籤(前置,後置,環繞,PointCut四種)代表要織入的邏輯
織入型別實現規則說明
前置織入 繼承AspectBeforeAttribute 在進入業務程式碼之前先執行【前置織入邏輯-》業務程式碼】
後置織入 繼承AspectAfterAttribute 在業務程式碼執行之後執行(即使有異常)【業務程式碼-》後置織入邏輯】
環繞織入 繼承AspectAroundAttribute 在業務程式碼之前和之前都執行【前置織入邏輯-》業務程式碼-》後置織入邏輯】
PointCut織入 繼承PointcutAttribute 掌控業務程式碼的執行權,這種最靈活【本文的TransactionScope功能就得用到它】

使用Autofac.Annotation元件案例:

一個開源的 netcore mvc role management 快速開發系統(選單,角色,許可權[精確到按鈕])