ABP框架的體系結(jié)構(gòu)及模塊系統(tǒng)講解
來源:易賢網(wǎng) 閱讀:1191 次 日期:2016-08-08 13:50:10
溫馨提示:易賢網(wǎng)小編為您整理了“ABP框架的體系結(jié)構(gòu)及模塊系統(tǒng)講解”,方便廣大網(wǎng)友查閱!

ABP框架是基于ASP.NET的Web開發(fā)框架,不過它遵循一種名為DDD(領(lǐng)域驅(qū)動設(shè)計)的設(shè)計模式原則,接下來我們就來看一下ABP框架的體系結(jié)構(gòu)及模塊系統(tǒng)講解

DDD分層

為了減少復雜性和提高代碼的可重用性,采用分層架構(gòu)是一種被廣泛接受的技術(shù)。

為了實現(xiàn)分層的體系結(jié)構(gòu),ABP遵循DDD(領(lǐng)域驅(qū)動設(shè)計)的原則,將分為四個層次:

展現(xiàn)層(Presentation):提供一個用戶界面,實現(xiàn)用戶交互操作。

應(yīng)用層(Application):進行展現(xiàn)層與領(lǐng)域?qū)又g的協(xié)調(diào),協(xié)調(diào)業(yè)務(wù)對象來執(zhí)行特定的應(yīng)用程序的任務(wù)。它不包含業(yè)務(wù)邏輯。

領(lǐng)域?qū)樱―omain):包括業(yè)務(wù)對象和業(yè)務(wù)規(guī)則,這是應(yīng)用程序的核心層。

基礎(chǔ)設(shè)施層(Infrastructure):提供通用技術(shù)來支持更高的層。例如基礎(chǔ)設(shè)施層的倉儲(Repository)可通過ORM來實現(xiàn)數(shù)據(jù)庫交互。

根據(jù)實際需要,可能會有額外添加的層。例如:

分布式服務(wù)層(Distributed Service):用于公開應(yīng)用程序接口供遠程客戶端調(diào)用。比如通過ASP.NET Web API和WCF來實現(xiàn)。

這些都是常見的以領(lǐng)域為中心的分層體系結(jié)構(gòu)。不同的項目在實現(xiàn)上可能會有細微的差別。

ABP的體系結(jié)構(gòu)

名單

一個簡單的解決方案,大致包含5個項目:

名單

每一層可以用一個或多個程序集來實現(xiàn)。

1.領(lǐng)域?qū)樱―omain)

領(lǐng)域?qū)泳褪菢I(yè)務(wù)層,是一個項目的核心,所有業(yè)務(wù)規(guī)則都應(yīng)該在領(lǐng)域?qū)訉崿F(xiàn)。

2.實體(Entity)

實體代表業(yè)務(wù)領(lǐng)域的數(shù)據(jù)和操作,在實踐中,通過用來映射成數(shù)據(jù)庫表。

3.倉儲(Repository)

倉儲用來操作數(shù)據(jù)庫進行數(shù)據(jù)存取。倉儲接口在領(lǐng)域?qū)佣x,而倉儲的實現(xiàn)類應(yīng)該寫在基礎(chǔ)設(shè)施層。

4.領(lǐng)域服務(wù)(Domain service)

當處理的業(yè)務(wù)規(guī)則跨越兩個(及以上)實體時,應(yīng)該寫在領(lǐng)域服務(wù)方法里面。

5.領(lǐng)域事件(Domain Event)

在領(lǐng)域?qū)幽承┨囟ㄇ闆r發(fā)生時可以觸發(fā)領(lǐng)域事件,并且在相應(yīng)地方捕獲并處理它們。

6.工作單元(Unit of Work)

工作單元是一種設(shè)計模式,用于維護一個由已經(jīng)被修改(如增加、刪除和更新等)的業(yè)務(wù)對象組成的列表。它負責協(xié)調(diào)這些業(yè)務(wù)對象的持久化工作及并發(fā)問題。

應(yīng)用層(Application)

應(yīng)用層提供一些應(yīng)用服務(wù)(Application Services)方法供展現(xiàn)層調(diào)用。一個應(yīng)用服務(wù)方法接收一個DTO(數(shù)據(jù)傳輸對象)作為輸入?yún)?shù),使用這個輸入?yún)?shù)執(zhí)行特定的領(lǐng)域?qū)硬僮?,并根?jù)需要可返回另一個DTO。在展現(xiàn)層到領(lǐng)域?qū)又g,不應(yīng)該接收或返回實體(Entity)對象,應(yīng)該進行DTO映射。一個應(yīng)用服務(wù)方法通常被認為是一個工作單元(Unit of Work)。用戶輸入?yún)?shù)的驗證工作也應(yīng)該在應(yīng)用層實現(xiàn)。ABP提供了一個基礎(chǔ)架構(gòu)讓我們很容易地實現(xiàn)輸入?yún)?shù)有效性驗證。建議使用一種像AutoMapper這樣的工具來進行實體與DTO之間的映射。

基礎(chǔ)設(shè)施層(Infrastructure)

當在領(lǐng)域?qū)又袨槎x了倉儲接口,應(yīng)該在基礎(chǔ)設(shè)施層中實現(xiàn)這些接口??梢允褂肙RM工具,例如EntityFramework或NHibernate。ABP的基類已經(jīng)提供了對這兩種ORM工具的支持。數(shù)據(jù)庫遷移也被用于這一層。

WEB與展現(xiàn)層(Web & Presentation)

Web層使用ASP.NET MVC和Web API來實現(xiàn)??煞謩e用于多頁面應(yīng)用程序(MPA)和單頁面應(yīng)用程序(SPA)。

在SPA中,所有資源被一次加載到客戶端瀏覽器中(或者先只加載核心資源,其他資源懶加載),然后通過AJAX調(diào)用服務(wù)端WebApi接口獲取數(shù)據(jù),再根據(jù)數(shù)據(jù)生成HTML代碼。不會整個頁面刷新?,F(xiàn)在已經(jīng)有很多SPA的JS框架,例如: AngularJs、 DurandalJs、BackboneJs、EmberJs。 ABP可以使用任何類似的前端框架,但是ABP提供了一些幫助類,讓我們更方便地使用AngularJs和DurandalJs。

在經(jīng)典的多頁面應(yīng)用(MPA)中,客戶端向服務(wù)器端發(fā)出請求,服務(wù)器端代碼(ASP.NET MVC控制器)從數(shù)據(jù)庫獲得數(shù)據(jù),并且使用Razor視圖生成HTML。這些被生成后的HTML頁面被發(fā)送回客戶端顯示。每顯示一個新的頁面都會整頁刷新。

SPA和MPA涉及到完全不同的體系結(jié)構(gòu),也有不同的應(yīng)用場景。一個管理后臺適合用SPA,博客就更適合用MPA,因為它更利于被搜索引擎抓取。

SignalR是一種從服務(wù)器到客戶端發(fā)送推送通知的完美工具。它能給用戶提供豐富的實時的體驗。

已經(jīng)有很多客戶端的Javascript框架或庫,JQuery是其中最流行的,并且它有成千上萬免費的插件。使用Bootstrap可以讓我們更輕松地完成寫Html和CSS的工作。

ABP也實現(xiàn)了根據(jù)Web API接口自動創(chuàng)建 Javascript的代碼函數(shù),來簡化JS對Web Api的調(diào)用。還有把服務(wù)器端的菜單、語言、設(shè)置等生成到JS端。(但是在我自己的項目中,我是把這些自動生成功能關(guān)閉的,因為必要性不是很大,而這些又會比較影響性能)。

ABP會自動處理服務(wù)器端返回的異常,并以友好的界面提示用戶。

ABP模塊系統(tǒng)

ABP框架提供了創(chuàng)建和組裝模塊的基礎(chǔ),一個模塊能夠依賴于另一個模塊。在通常情況下,一個程序集就可以看成是一個模塊。在ABP框架中,一個模塊通過一個類來定義,而這個類要繼承自AbpModule。

譯者注:如果學習過Orchard的朋友,應(yīng)該知道m(xù)odule模塊的強大了。模塊的本質(zhì)就是可重用性,你可以在任意的地方去調(diào)用,而且通過實現(xiàn)模塊,你寫的模塊也可以給別人用。

Assembly程序集:Assembly是一個包含來程序的名稱,版本號,自我描述,文件關(guān)聯(lián)關(guān)系和文件位置等信息的一個集合。最簡單的理解就是:一個你自己寫的類庫生成的dll就可以看做是一個程序集,這個程序集可以包括很多類,類又包括很多方法等。

.net可以通過反射獲取一個程序集中的類以及方法。

下面的例子,我們開發(fā)一個可以在多個不同應(yīng)用中被調(diào)用MybolgApplication模塊,代碼如下: 

public class MyBlogApplicationModule : AbpModule //定義

{

 public override void Initialize() //初始化

 {

 IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());

 //這行代碼的寫法基本上是不變的。它的作用是把當前程序集的特定類或接口注冊到依賴注入容器中。

 }

}

ABP框架會掃描所有的程序集,并且發(fā)現(xiàn)AbpModule類中所有已經(jīng)導入的所有類,如果你已經(jīng)創(chuàng)建了包含多個程序集的應(yīng)用,對于ABP,我們的建議是為每一個程序集創(chuàng)建一個Module(模塊)。

生命期事件

在一個應(yīng)用中,abp框架調(diào)用了Module模塊的一些指定的方法來進行啟動和關(guān)閉模塊的操作。我們可以重載這些方法來完成我們自己的任務(wù)。

ABP框架通過依賴關(guān)系的順序來調(diào)用這些方法,假如:模塊A依賴于模塊B,那么模塊B要在模塊A之前初始化,模塊啟動的方法順序如下:

1.PreInitialize-B

2.PreInitialize-A

3.Initialize-B

4.Initialize-A

5.PostInitialize-B

6.PostInitialize-A

下面是具體方法的說明:

1.PreInitialize

預初始化:當應(yīng)用啟動后,第一次會調(diào)用這個方法。在依賴注入注冊之前,你可以在這個方法中指定自己的特別代碼。舉個例子吧:假如你創(chuàng)建了一個傳統(tǒng)的登記類,那么你要先注冊這個類(使用IocManager對登記類進行注冊),你可以注冊事件到IOC容器。等。

2.Initialize

初始化:在這個方法中一般是來進行依賴注入的注冊,一般我們通過IocManager.RegisterAssemblyByConvention這個方法來實現(xiàn)。如果你想實現(xiàn)自定義的依賴注入,那么請參考依賴注入的相關(guān)文檔。

3.PostInitialize

提交初始化:最后一個方法,這個方法用來解析依賴關(guān)系。

4.Shutdown

關(guān)閉:當應(yīng)用關(guān)閉以后,這個方法被調(diào)用。

模塊依賴(Module dependencies)

Abp框架會自動解析模塊之間的依賴關(guān)系,但是我們還是建議你通過重載GetDependencies方法來明確的聲明依賴關(guān)系。

[DependsOn(typeof(MyBlogCoreModule))]//通過注解來定義依賴關(guān)系

public class MyBlogApplicationModule : AbpModule

{

 public override void Initialize()

 {

  IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());

 }

}

例如上面的代碼,我們就聲明了MyBlogApplicationModule和MyBlogCoreModule的依賴關(guān)系(通過屬性attribute),MyBlogApplicationModule這個應(yīng)用模塊依賴于MyBlogCoreModule核心模塊,并且,MyBlogCoreModule核心模塊會在MyBlogApplicationModule模塊之前進行初始化。

如何自定義的模塊方法

我們自己定義的模塊中可能有方法被其他依賴于當前模塊的模塊調(diào)用,下面的例子,假設(shè)模塊2依賴于模塊1,并且想在預初始化的時候調(diào)用模塊1的方法。

public class MyModule1 : AbpModule

{

 public override void Initialize() //初始化模塊

 {

 IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());//這里,進行依賴注入的注冊。

 }

 public void MyModuleMethod1()

 {

 //這里寫自定義的方法。

 }

}

[DependsOn(typeof(MyModule1))]

public class MyModule2 : AbpModule

{

 private readonly MyModule1 _myModule1;

 public MyModule2(MyModule1 myModule1)

 {

 _myModule1 = myModule1;

 }

 public override void PreInitialize()

 {

 _myModule1.MyModuleMethod1(); //調(diào)用MyModuleMethod1的方法。

 }

 public override void Initialize()

 {

 IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());

 }

}

就這樣,就把模塊1注入到了模塊2,因此,模塊2就能調(diào)用模塊1的方法了。

更多信息請查看網(wǎng)絡(luò)編程
易賢網(wǎng)手機網(wǎng)站地址:ABP框架的體系結(jié)構(gòu)及模塊系統(tǒng)講解
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 加入群交流 | 手機站點 | 投訴建議
工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
聯(lián)系電話:0871-65317125(9:00—18:00) 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
咨詢QQ:526150442(9:00—18:00)版權(quán)所有:易賢網(wǎng)