為了防止不提供原網址的轉載,特在這裡加上原文鏈接: http://www.cnblogs.com/skabyy/p/7295533.html ABP是 ASP.NET Boilerplate Project 的簡稱。ABP是基於 DDD (領域驅動設計)的框架。ABP包含眾多組件,包括依賴註入、動態 ...
為了防止不提供原網址的轉載,特在這裡加上原文鏈接:
http://www.cnblogs.com/skabyy/p/7295533.html
ABP是 ASP.NET Boilerplate Project 的簡稱。ABP是基於DDD(領域驅動設計)的框架。ABP包含眾多組件,包括依賴註入、動態API、審計日誌、許可權控制等等。在大部分的ABP教材中,會推薦使用模板(https://aspnetboilerplate.com/Templates)來創建ABP工程。然而在實際使用中(至少在我的情況里)一般都需要手工搭建框架而非使用模板。手工搭建有下麵幾個好處:
- 模板創建的工程有很多不需要的東西需要調整或刪除,手工搭建免去了這些麻煩;
- 手工搭建框架能更自由地根據實際需求進行自定義配置和擴展;
- 手工搭建能幫助你更深入地理解ABP框架。
由於手工搭建ABP框架材料較少,我搭建時踩了不少坑。所以在這裡記錄一下搭建框架的核心步驟,以免以後重新摸索,同時與大家分享,歡迎拍磚。下麵我們以開發一個簡單的微博應用為例來展示如何使用ABP框架。
新建VS項目
用VS新建Web MVC項目,項目名稱為MyTweet.Web
。同時新建解決方案,解決方案名稱為MyTweet
。要註意的一點是ABP只支持.NET 4.6以上版本,所以新建項目時記得選.NET Framework 4.6以上的版本。
接下來,我們遵循DDD的原則,新建以下幾個層次的項目:
- 展現層(Presentation),負責用戶界面與用戶交互。在我們這個應用中,展現層是.NET MVC,包括Controller以及前端代碼,實現在項目
MyTweet.Web
中。 - 應用層(Application),負責展現層與領域層之間的協調。實現在項目
MyTweet.Application
中。 - 領域層(Domain),負責業務對象與業務邏輯。實現在項目
MyTweet.Domain
中。 - 基礎設施層(Infrastructure),提供一些通用的方法。實現在項目
MyTweet.Infrastructure
中。
新建好項目後,還需要設置引用依賴關係。在此不再贅述。
安裝ABP相關的NuGet包
安裝Abp
包到所有項目。
安裝Abp.Web.Mvc
和Abp.Web.Api
到MyTweet.Web
。
創建模塊
ABP提供了模塊系統。使用模塊能方便地管理各個組件的初始化與依賴關係。一般來說,每個項目都會建一個模塊。由於本篇只用到了MyTweet.Web
和MyTweet.Application
,所以先只新建這兩個模塊。
在MyTweet.Application
目錄下新建類MyTweetApplicationModule
,並繼承自AbpModule
。如圖:
模塊中的Initialize
方法定義了模塊初始化時執行的操作。目前只做了IoC依賴註入的操作。
另外,在MyTweet.Web/App_Start
目錄下新建類MyTweetWebModule
,同樣也需要繼承自AbpModule
,並且,這個模塊還需要依賴AbpWebApiModule
(WebAPI需要這個模塊),MyTweetApplicationModule
。如圖:
最後,為了讓程式運行時能識別並執行模塊,需要修改入口方法。.NET MVC的入口方法在Global.asax.cs
文件中,如下圖,MvcApplication
修改為繼承AbpWebApplication<MyTweetWebModule>
,並相應地修改Application_Start
方法。
WebAPI
我們使用WebAPI的方式定義前後端交互的介面。當然,直接使用MVC的方法也是可以的。這裡只是單純為了試用ABP動態WebAPI的用法而使用的WebAPI。
我們將實現兩個介面:
GetTweets
介面,GET方法,用於查詢出所有微博。CreateTweet
介面,POST方法,用於新增一條微博。
因為我們還沒實現資料庫訪問功能,所以現在還不會真正實現這兩個介面,這兩個介面現在只讓它們返回一些測試數據。
在ABP框架下實現WebAPI十分方便,ABP能夠使用反射的方法自動從應用層AppService
的public方法生成WebAPI介面。只需在MyTweetModule
的初始化方法添加代碼定義動態ApiController
生成規則:
這些代碼會在MyTweetApplicationModule
的程式集中,將所有IApplicationService
的實現類動態生成ApiController
,並且根據方法名對public方法綁定相應的HTTP Method動詞。
比如,GetTweets
綁定為GET方法,PutTweet
綁定為PUT方法,其他名稱的方法像CreateTweet
綁定為POST方法。
(這裡有一個例外,Get開頭的方法如果參數是一個object——一個DTO的話,那這個方法會被綁定為POST方法。)
生成的WebAPI介面的訪問路徑為/api/services/MyTweet/{AppSvcName}/{ActionName}
,其中{AppSvcName}
是IApplicationService
實現類的類名(去掉尾碼AppService
),{ActionName}
是方法名。
接下來我們實現GetTweets
和CreateTweet
兩個介面:
現在只是簡單的讓這兩個介面隨便返回一些結果。GetTweets
是接收一個字元串參數的GET介面,CreateTweet
是接收一個字元串s
、一個整數s
的POST介面(C#與JavaScript對大小寫的編碼規範不同是一件很煩人的事,幸好ABP框架做了自動轉換)。這兩個介面的路徑分別為/api/services/MyTweet/MyTweet/GetTweets
和/api/services/MyTweet/MyTweet/CreateTweet
。
最後測試一下,運行MyTweet.Web
項目,GET介面直接在瀏覽器就能訪問:
POST介面可以用Postman工具來訪問:
大功告成!
你訪問API的時候可能會出現"Empty or invalid anti forgery header token"的錯誤,這是因為某些ABP版本預設開啟了CSRF防禦。在MyTweetWebModule
的PreInitialize
方法加上下麵這行代碼關閉CSRF防禦就可以了。
Configuration.Modules.AbpWeb().AntiForgery.IsEnabled = false;
Abp Module
最後簡要介紹下ABP的模塊系統。更詳細的講解可查閱官網的文檔https://aspnetboilerplate.com/Pages/Documents/Module-System。
模塊主要用來管理系統初始化和關閉時要執行的操作。ABP在系統初始化和關閉時根據模塊間依賴關係執行相應的操作。
定義一個模塊只需要繼承AbpModule
。我們可以用DependsOn
標簽來聲明模塊間的依賴關係(ABP框架會自動解析依賴關係,但建議使用顯式的聲明)。
一個模塊會有如下方法,我們可以重載這些方法來定義模塊初始化/關閉時要做的操作:
PreInitialize
:預初始化Initialize
:初始化PostInitialize
:後初始化Shutdown
:關閉
應用啟動時會根據模塊的依賴順序進行初始化。比如有模塊A和模塊B,模塊A依賴模塊B,那麼初始化的執行順序為:
- B的
PreInitialize
- A的
PreInitialize
- B的
Initialize
- A的
Initialize
- B的
PostInitialize
- A的
PostInitialize
關閉則按照依賴相反順序:
- A的
Shutdown
- B的
Shutdown
最後還有一個問題:應用啟動時,ABP框架如何知道要初始化哪些模塊?答案在入口函數方法:
ABP框架解析MyTweetModule
所依賴的模塊,按順序初始化這些模塊(包括MyTweetModule
)。