欧美日韩电影精品视频_亚洲天堂一区二区三区四区_亚洲欧美日韩国产综合_日韩精品一区二区三区中文_為您提供優質色综合久久88色综合天天

您的位置:首頁(yè) > 公司 >

聊聊 ASP.NET 6 整潔架構(gòu)開(kāi)發(fā)模板

2023-06-21 18:09:56 來(lái)源:博客園

評(píng)論

大家好,我是Edison。

最近看了一些整潔架構(gòu)(CleanArchitecture)的文章,自己和同事也簡(jiǎn)單寫(xiě)了一個(gè)基于整潔架構(gòu)的ASP.NET 6開(kāi)發(fā)模板在玩。這里就僅僅拋個(gè)磚,案例主要以自己根據(jù)小組實(shí)際情況做了一些裁剪,可能不具有通用的應(yīng)用性,大家看看就好。


【資料圖】

整潔架構(gòu)的產(chǎn)生背景

微服務(wù)架構(gòu)讓DDD(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))煥發(fā)了第二春,在DDD的推動(dòng)下,DDD的分層架構(gòu)被逐漸推上了舞臺(tái)。DDD的分層架構(gòu)就有好多種,例如整潔架構(gòu)、CQRS和六邊形架構(gòu)等等,每種架構(gòu)模式雖然提出的時(shí)代和背景不同,但其核心理念都是為了設(shè)計(jì)出“高內(nèi)聚低耦合”的架構(gòu),從而能夠?qū)崿F(xiàn)架構(gòu)的演進(jìn)。

DDD分層架構(gòu)

在歐創(chuàng)新老師的《DDD實(shí)戰(zhàn)課》中,給出了一個(gè)優(yōu)化后的DDD四層架構(gòu),我們可以從下面這張圖中看到,從上到下分別是:用戶接口層、應(yīng)用層、領(lǐng)域?qū)雍突A(chǔ)層。

與傳統(tǒng)的三層架構(gòu)不同,DDD四層架構(gòu)的重點(diǎn)在于引入了一個(gè)領(lǐng)域?qū)?。領(lǐng)域?qū)拥淖饔檬?strong>實(shí)現(xiàn)企業(yè)核心業(yè)務(wù)邏輯,通過(guò)各種校驗(yàn)手段保證業(yè)務(wù)的正確性。領(lǐng)域?qū)又饕w現(xiàn)領(lǐng)域模型的業(yè)務(wù)能力,它用來(lái)表達(dá)業(yè)務(wù)概念、業(yè)務(wù)狀態(tài)和業(yè)務(wù)規(guī)則。領(lǐng)域?qū)影壕酆细?、?shí)體、值對(duì)象、領(lǐng)域服務(wù)等領(lǐng)域模型中的領(lǐng)域?qū)ο?。?duì)于領(lǐng)域?qū)?,領(lǐng)域模型的業(yè)務(wù)邏輯主要由實(shí)體和領(lǐng)域服務(wù)來(lái)實(shí)現(xiàn)。對(duì)于實(shí)體,一般建議采用充血模型來(lái)實(shí)現(xiàn)所有與之相關(guān)的業(yè)務(wù)功能。對(duì)于領(lǐng)域服務(wù),一般當(dāng)單個(gè)實(shí)體不能實(shí)現(xiàn)某些功能時(shí),領(lǐng)域服務(wù)才會(huì)出馬,組合聚合內(nèi)的多個(gè)實(shí)體來(lái)實(shí)現(xiàn)復(fù)雜的業(yè)務(wù)邏輯。下圖中展示了傳統(tǒng)的三層架構(gòu)與DDD四層架構(gòu)的對(duì)應(yīng)關(guān)系:

整潔架構(gòu)簡(jiǎn)單介紹

簡(jiǎn)而言之,整潔架構(gòu)是組織軟件體系結(jié)構(gòu)的原則,可以輕松面對(duì)未來(lái)的不確定性,方便代碼的重構(gòu)。同時(shí),它可以幫助我們?yōu)樘囟ǖ念I(lǐng)域模型構(gòu)建服務(wù),從而為將來(lái)可能的微服務(wù)體系結(jié)構(gòu)做好準(zhǔn)備。在Jason Taylor的這篇文章中《Clean Architecture with .NET Core: Gettting Started》中給出了一張經(jīng)典的圖:

在整潔架構(gòu)中,所有依賴關(guān)系都向內(nèi)流動(dòng),而核心層不依賴于其他任何層。基礎(chǔ)設(shè)施層和展示層依賴于核心層,而不是彼此依賴。在Jason Taylor給出的圖中,只有三個(gè)圓圈,但在實(shí)際中,你可能需要更多,但是你可以以此作為起點(diǎn),只需要記住讓所有依賴都指向內(nèi)部即可。這里的內(nèi)部,我們可以將其稱為ApplicationCore,也就是Application + Domain。

整潔架構(gòu)模板搭建

這里我試著搭建了一個(gè)基于ASP.NET 6的開(kāi)發(fā)模板,展示層有兩種可選:ASP.NET WebAPI / Blazor。需要說(shuō)明是:該模板僅僅是結(jié)合我司實(shí)際情況的構(gòu)想,沒(méi)有遵循DDD的一些原則思想(DDD是個(gè)好東西,但不是所有項(xiàng)目都適用,也不是所有團(tuán)隊(duì)都可以用好),也不具有廣泛應(yīng)用性,各位看官看看一笑而過(guò)就好。

在我司(一家制造業(yè)工廠的IT部),基于我們組的實(shí)際人員情況中(開(kāi)發(fā)基礎(chǔ)能力較弱,以前的工作基本以運(yùn)維為主,很少做開(kāi)發(fā)工作)和開(kāi)發(fā)項(xiàng)目的綜合復(fù)雜度(嚴(yán)格來(lái)說(shuō),復(fù)雜度并不高,以后臺(tái)管理信息系統(tǒng)為主),我不想引入太多DDD的概念增加學(xué)習(xí)成本,因此ValueObject和Domain Service被我移除了,但是充血模型的Entity是我們所倡導(dǎo)的,因此,最終的結(jié)構(gòu)如下圖所示:

對(duì)于展示層,分別使用WebAPI和Blazor實(shí)現(xiàn)API和UI的宿主;對(duì)于核心層(ApplicationCore),包含 Application 和 Domain 兩個(gè).NET 6.0類(lèi)庫(kù)項(xiàng)目。

(1)Application定義了Services、Handlers(對(duì)于MQ的Consumers)、Validators(基于FluentValidation的Validators)以及 各種Models(DTO、VO,以及基于AutoMapper的MappingProfiles)。

(2)Domain則定義了實(shí)體、枚舉、異常、常量等。這一層無(wú)需引入過(guò)多概念,只需要在原有實(shí)體的基礎(chǔ)上,使用充血模型,讓實(shí)體的行為豐富起來(lái)即可,這也可以讓開(kāi)發(fā)人員很快適應(yīng)和模仿。

對(duì)于基礎(chǔ)設(shè)施層,也是一個(gè).NET 6.0類(lèi)庫(kù),主要包含了基于EF Core的上下文(DbContext)、實(shí)體映射關(guān)系(EntityConfiguration)、Repositories、Gateways(針對(duì)依賴的外部接口HttpClient實(shí)現(xiàn),可以用HttpClientFactory來(lái)實(shí)現(xiàn),也可以用WebApiClient之類(lèi)的封裝項(xiàng)目)、Cache(比如RedisClient的注冊(cè))、MessageQueue(比如KafkaClient的注冊(cè),取決于你們組用了什么MQ)等。

除了上面的四層之外,設(shè)計(jì)一個(gè)CrossCuting的Shared類(lèi)庫(kù),用于存放一些各個(gè)層都可以復(fù)用(引用)的幫助類(lèi)、擴(kuò)展方法、基類(lèi)等,用于減少重復(fù)。整個(gè)項(xiàng)目在Visual Studio中的解決方案目錄如下圖所示:

整個(gè)項(xiàng)目在Visual Studio中的解決方案目錄如下圖所示:

最終的依賴關(guān)系如下:(1)Domain類(lèi)庫(kù)只引用Shared類(lèi)庫(kù)(即CrossCutting)。(2)Application類(lèi)庫(kù)引用:Domain、Infrastructure、Shared

這里我們沒(méi)有讓Application不依賴于Infrastructure,是因?yàn)槲覀兊腄B技術(shù)棧已經(jīng)固定,而且大家也比較習(xí)慣于在Infrastructure里邊定義Repository、Gateway等的interface,而不是在Application里面定義這些interface,Infrastructure通過(guò)應(yīng)用Application來(lái)做實(shí)現(xiàn)。

(3)Infrastructure類(lèi)庫(kù)引用:Domain、Shared

(4)Web項(xiàng)目引用:Application、Shared(其實(shí)這里Application引用了Shared,Web項(xiàng)目無(wú)需再添加引用)

(5)WebUI項(xiàng)目引用:Application、Shared(其實(shí)這里Application引用了Shared,Web項(xiàng)目無(wú)需再添加引用)通常情況下,WebAPI和WebUI項(xiàng)目二者只選選擇一個(gè),因此新項(xiàng)目創(chuàng)建好之后,刪除其中一個(gè)。

(6)Application.UnitTests項(xiàng)目引用:Application(7)Domain.UnitTests項(xiàng)目引用:Domain

(8)Web.IntegrationTests項(xiàng)目引用:Web

在實(shí)際模板中,針對(duì)ServiceCollection和ApplicationBuilder寫(xiě)了很多擴(kuò)展方法,用于一些常見(jiàn)組件的注冊(cè),例如Swagger、CAP(Event Bus)、Redis Client、健康檢查EndPoints、KeyCloak鑒權(quán)啟用等等。開(kāi)發(fā)者只需要根據(jù)需要在配置文件中添加或移除對(duì)應(yīng)部分的config即可,這些擴(kuò)展方法會(huì)根據(jù)配置文件中是否有這部分的config來(lái)判斷是否需要注冊(cè)。因此,大部分情況下,小組的開(kāi)發(fā)者要做的僅僅是做減法。比如,如果項(xiàng)目只用到了Cache沒(méi)有用到EventBus,那么只需要在配置中移除EventBus的部分即可,不用改任何一句代碼。又如,通常大部分項(xiàng)目里我們只會(huì)保留一個(gè)UnitTest類(lèi)庫(kù),而不是讓三個(gè)都在項(xiàng)目中,因?yàn)槲覀兊木Σ蛔阋詫?xiě)三種類(lèi)型的Test項(xiàng)目。但是某些大一點(diǎn)的項(xiàng)目,對(duì)質(zhì)量有要求的,我們可能會(huì)寫(xiě)兩中類(lèi)型的Test項(xiàng)目。

模板上傳Nuget倉(cāng)庫(kù)

這里我們主要通過(guò)將其發(fā)布為一個(gè)Nuget包上傳到企業(yè)內(nèi)部的Nuget倉(cāng)庫(kù),然后客戶端可以通過(guò)安裝這個(gè)nuget包將其添加到Visual Studio中的項(xiàng)目模板中。

當(dāng)然,也可以直接通過(guò)dotnet new命令直接通過(guò)模板創(chuàng)建新項(xiàng)目。

-- installdotnet new install CleanArchitectureTemplate-- uninstalldotnet new uninstall CleanArchitectureTemplate

同理,當(dāng)將開(kāi)發(fā)模板發(fā)布了新的nuget包,客戶端也可以通過(guò)更新nuget包的方式將模板進(jìn)行更新,以便下次可以使用新的模板進(jìn)行項(xiàng)目的開(kāi)發(fā)。

-- checkdotnet new --update-check-- applydotnet new --update-apply

關(guān)于如何通過(guò)Nuget上傳開(kāi)發(fā)模板,可以參考Microsoft的這一篇文檔:https://learn.microsoft.com/zh-cn/dotnet/core/tools/custom-templates

小結(jié)

本文介紹了DDD分層架構(gòu)的背景、整潔架構(gòu)的概念,隨后分享了一個(gè)基于我所在小組的實(shí)際情況的一個(gè)整潔架構(gòu)的模板案例。在實(shí)際情況中,ABP vNext也是一不錯(cuò)的選擇,對(duì)DDD有興趣應(yīng)用的建議仔細(xì)看看。

參考代碼

GitHub:https://github.com/EdisonChou/CleanArchitectureTemplate

參考資料

Jason Taylor,《Clean Architecture with .NET Core: Gettting Started》

歐創(chuàng)新,極客時(shí)間《DDD實(shí)戰(zhàn)課》

Jacky Fei,《基于ASP.NET 6的整潔架構(gòu)》

Alexander Zhao,《.NET Core整潔架構(gòu)入門(mén)》

Denny Zhang,《領(lǐng)域驅(qū)動(dòng)架構(gòu)及其演變歷史》

作者:周旭龍

出處:https://edisonchou.cnblogs.com

本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文鏈接。

關(guān)鍵詞:

[責(zé)任編輯:]

相關(guān)閱讀