一.DDD分層架構(gòu)介紹
本篇繼續(xù)探討web應(yīng)用架構(gòu),講基于DDD風格下最初的領(lǐng)域模型架構(gòu),不同于DDD風格下CQRS架構(gòu),二者架構(gòu)主要區(qū)別是領(lǐng)域?qū)拥淖兓?架構(gòu)的演變是從領(lǐng)域模型到CQRS, 一開始DDD是用領(lǐng)域模型的分層架構(gòu),用單一的領(lǐng)域模型處理業(yè)務(wù)邏輯的所有方法,特別是命令和查詢,這可能導致復雜性直線上升,CQRS是留住了DDD的優(yōu)點又能使實現(xiàn)變得簡單高效。
同樣作為DDD領(lǐng)域驅(qū)動設(shè)計下的支持架構(gòu)包括:領(lǐng)域模型架構(gòu)和CQRS架構(gòu)。雖然CQRS架構(gòu)相比領(lǐng)域模型架構(gòu)更受歡迎推薦,但領(lǐng)域模型架構(gòu)也同樣需要了解和掌握。
在軟件行業(yè)經(jīng)過多年的傳統(tǒng)三層開發(fā)后,演變出了DDD領(lǐng)域驅(qū)動設(shè)計。傳統(tǒng)三層是UI層調(diào)用BLL層,BLL層調(diào)用DAL層,每層都有自己熟知的職責。但是缺點是編譯時依賴關(guān)系由上而下運行,是一種高藕合,依賴程序太大,而在設(shè)計原則中應(yīng)該是低藕合,越低越好。
1.1 Clean architecture
Clean architecture 被稱為“干凈架構(gòu)"。遵循依賴倒置原則以及領(lǐng)域驅(qū)動設(shè)計原則 (DDD) 的應(yīng)用程序傾向于達到類似的架構(gòu)。此依賴關(guān)系被倒置是:基礎(chǔ)架構(gòu)層和實現(xiàn)細節(jié)依賴于領(lǐng)域?qū)?,通過在領(lǐng)域?qū)佣x抽象或接口。然后由基礎(chǔ)設(shè)施層中定義的具體類型來實現(xiàn)接口。理解這點很重要。
比例在上篇項目中,由Equinox.Infra.Data數(shù)據(jù)訪問層的Repository文件夾來實現(xiàn)領(lǐng)域?qū)拥腎Repository接口。由Equinox.Infra.CrossCutting.Bus 層 命令總線的InMemoryBus類實現(xiàn)領(lǐng)域?qū)拥腎MediatorHandler接口。
比例在上篇項目中,由Equinox.Infra.Data數(shù)據(jù)訪問層的Repository文件夾來實現(xiàn)領(lǐng)域?qū)拥腎Repository接口。由Equinox.Infra.CrossCutting.Bus 層 命令總線的InMemoryBus類實現(xiàn)領(lǐng)域?qū)拥腎MediatorHandler接口。
下圖是DDD干凈架構(gòu)多層以"同心圓"形式展示。通過下圖可以了解到:依賴關(guān)系流向最里面的圓。application core位于此關(guān)系圖的核心位置而得名,該application core沒有任何依賴項。application core的Entities和Interfaces位于正中心,正中心外圈是application core的域服務(wù),域服務(wù)通常調(diào)用內(nèi)圈中定義的Interfaces接口。application core外面UI(應(yīng)用服務(wù)層)和基礎(chǔ)設(shè)施層都依賴于application core。

User Interface是表現(xiàn)層包括:控制器和視圖模型(包括了應(yīng)用服務(wù)層)。
Infrastructure是基礎(chǔ)設(shè)施層包括:倉儲,其它服務(wù)實現(xiàn)。
application core是領(lǐng)域?qū)影ǎ侯I(lǐng)域服務(wù),領(lǐng)域?qū)嶓w,領(lǐng)域接口 (來基礎(chǔ)設(shè)施層來實現(xiàn))。
下圖更好的反映了DDD各層的依賴關(guān)系,實線箭頭表示編譯時依賴關(guān)系,而虛線箭頭表示僅運行時依賴關(guān)系。領(lǐng)域?qū)邮羌軜?gòu)的核心層,不依賴于基礎(chǔ)設(shè)施層,該層是可測試的。基礎(chǔ)設(shè)施層引用領(lǐng)域?qū)觼韺崿F(xiàn)數(shù)據(jù)持久化或橫切關(guān)注點。

下圖是asp.net core web應(yīng)用程序在DDD領(lǐng)域模型方案中完整構(gòu)架,展現(xiàn)了各層明確的職責分布,虛線指編譯依賴關(guān)系,也可以理解為項目引用關(guān)系,實線則是運行依賴關(guān)系。

在了解DDD領(lǐng)域模型構(gòu)架分層后。接下來分析eShopOnWeb項目,來掌握DDD下的領(lǐng)域模型架構(gòu)。下面是二個有代表性的領(lǐng)域模型架構(gòu)項目,以微軟的官方示例eShopOnWeb項目做重點分析。在分析中主要去了解領(lǐng)域?qū)觾?nèi)部是怎么實現(xiàn)的,以及業(yè)務(wù)處理流程代碼實現(xiàn)。
二.項目介紹
2.1. IBuyStuff-dm項目
IBuyStuff-dm項目是"Microsoft.net企業(yè)級應(yīng)用架構(gòu)設(shè)計"一書的項目案例(asp.net mvc項目)。從github上下載源碼,需要在IBuyStuff.Server項目中安裝mvc5(沒果沒有mvc5), 安裝命令如下:
Install-Package Microsoft.AspNet.Mvc -Version 5.0.0
項目結(jié)構(gòu)如下所示(左圖為項目結(jié)構(gòu),右圖為領(lǐng)域?qū)佣€類庫):

項目分層說明: IBuyStuff.Server為表現(xiàn)層
IBuyStuff.Application為應(yīng)用服務(wù)層
IBuyStuff.Domain為領(lǐng)域模型層
IBuyStuff.Domain.Services為領(lǐng)域服務(wù)層
IBuyStuff.Persistence為基礎(chǔ)設(shè)施層
2.2 eShopOnWeb項目
在ASP.NET Core技術(shù)出來后,微軟官方給出了一個eShopOnWeb項目案例(asp.net core mvc項目)。該項目演示了一些原則和建議, 是一個簡單在線商店,支持瀏覽襯衫、咖啡杯和其他市場產(chǎn)品名錄。項目結(jié)構(gòu)如下所示:

項目分層說明:
Web包括表現(xiàn)層,應(yīng)用服務(wù)層。其中Services文件夾和Interfaces文件夾代表是應(yīng)用服務(wù)層,在上篇中說到,表現(xiàn)層和應(yīng)用服務(wù)層都屬于前端系統(tǒng)范圍。
ApplicationCore領(lǐng)域?qū)?,包括了領(lǐng)域內(nèi)部的所有實現(xiàn)。
Infrastructure基礎(chǔ)設(shè)施層。主要是EF數(shù)據(jù)持久化。
tests文件夾包括了一系列完整的測試項目。
三. 項目配置
3.1 啟用數(shù)據(jù)庫類型
下載了eShopOnWeb項目后,在Startup.cs的ConfigureDevelopmentServices方法中,可以選擇是基于內(nèi)存或sql server存儲,我們選擇使用sql server。
public void ConfigureDevelopmentServices(IServiceCollection services)
{ // use in-memory database // ConfigureInMemoryDatabases(services); // use real database
ConfigureProductionServices(services);
}
3.2 修改數(shù)據(jù)庫鏈接地址
修改appsettings.json文件中的數(shù)據(jù)庫連接,對應(yīng)的兩個數(shù)據(jù)庫CatalogDb,Identity。
CatalogDb數(shù)據(jù)庫用于商店的目錄數(shù)據(jù)和購物車信息,Identity數(shù)據(jù)庫用于應(yīng)用程序的用戶憑據(jù)和身份數(shù)據(jù)。
3.3 同步到數(shù)據(jù)庫
在vs2017中使用“程序包管理器控制臺“默認項目選擇Infrastructure,同步兩個EF上下文到數(shù)據(jù)庫。
PM> Update-Database -C AppIdentityDbContext
PM> Update-Database -C CatalogContext
同步后,生成的兩個數(shù)據(jù)庫,下面展示了CatalogDb業(yè)務(wù)數(shù)據(jù)庫的關(guān)系圖,如下所示:

Orders表是用戶訂單信息,包含了送貨地址信息。
OrderItems表是訂單商品信息。
Catalog是商城商品信息
CatalogBrand是商城商品品牌信息
CatalogType是商城商品類別。比如T-Shirt襯衫,Mug杯子
Baskets 是購物車
BasketItem是購物車商品信息。
啟動運行eShopOnWeb程序,使用默認的用戶名和密碼進行登錄: demouser@microsoft.com Pass@word1。 項目包括二個模塊功能,一個是訂單管理,一個是用戶管理。

參考資料
Microsoft.NET企業(yè)級應(yīng)用架構(gòu)設(shè)計 第二版