使用ASP.NET Core的清潔體系結構的起點。乾淨的體系結構只是一系列名稱中的最新架構,用於相同的鬆散耦合,依賴性與內向體系結構。您還會發現它名為Hexagonal,端口和適配器或洋蔥架構。
在NimblePros的“清潔架構”課程中了解有關乾淨體系結構的更多信息和此模板。使用代碼ardalis節省20%。
史蒂夫·史密斯(Steve Smith)和朱莉·萊爾曼(Julie Lerman)在DDD基礎課程中使用了該架構。
?請與Steve的公司NimblePros聯繫,以提供清潔架構或DDD培訓和/或為您的團隊實施幫助。
了解如何從NimblePros培訓師Sarah“ Sadukie” Dutkiewicz和Steve“ Ardalis” Smith實施清潔建築。
如果您願意或正在使用此項目學習或啟動解決方案,請給它一顆星。謝謝!
或者,如果您真的很慷慨,我們現在支持GitHub贊助 - 請參閱上面的按鈕。
我請宣布,亞馬遜AWS的FOSS基金已選擇為該項目頒發12個月的讚助。謝謝您,感謝我所有其他過去和現在的讚助商!
默認情況下,該網站使用HTTPS,並希望您擁有自簽名的開發人員證書以供本地主機使用。如果您遇到了Chrome的錯誤,請參閱此答案以獲取緩解說明。
主分支現在使用.NET 9 。這與Nuget軟件包版本10.x相對應。可以使用以前的版本 - 請參閱我們的發行版。
要使用此模板,有一些選擇:
dotnet new (推薦)安裝首先,從Nuget(https://www.nuget.org/packages/ardalis.cleanarchitecture.template/)安裝模板:
dotnet new install Ardalis.CleanArchitecture.Template您可以通過與-?選項:
dotnet new clean - arch - ?
ASP.NET Clean Architecture Solution (C # )
Author: Steve Smith @ardalis , Erik Dahl
Usage:
dotnet new clean - arch [ options ] [ template options ]
Options:
- n , -- name < name > The name for the output being created. If no name is specified , the name of the output
directory is used.
- o , -- output < output > Location to place the generated output.
-- dry - run Displays a summary of what would happen if the given command line were run if it would result
in a template creation.
-- force Forces content to be generated even if it would change existing files.
-- no - update-check Disables checking for the template package updates when instantiating a template.
-- project < project > The project that should be used for context evaluation.
- lang , -- language < C # > Specifies the template language to instantiate.
-- type < project > Specifies the template type to instantiate.
Template options:
-as , -- aspire Include .NET Aspire.
Type: bool
Default : false在成功安裝之後,您應該在dotnet new list中的模板列表中看到模板。查找帶有“ Clean-Arch”簡稱的“ ASP.NET乾淨體系結構解決方案”。
導航到您希望創建解決方案文件夾的父目錄。
運行此命令以在子文件夾名稱中創建解決方案結構Your.ProjectName :
dotnet new clean-arch -o Your.ProjectName
將創建Your.ProjectName目錄和解決方案文件,其中將是您所有的新解決方案內容,適當地命名為空間,並準備運行/測試!
例子: 
感謝@dahlsailrunner的幫助!
已知問題:
截至版本9,此解決方案模板僅包括使用buddendpoints庫對API端點的支持。如果您想使用我的Apiendpoints庫,剃刀頁和/或控制器,則可以使用其中的最後一個模板,版本7.1。或者,安裝後它們很容易添加到此模板中。
要使用ardalis.apiendpoint代替(或除了)buddendpoints,只需添加參考並使用文檔中的基類。
dotnet add package Ardalis.ApiEndpoints您需要將對控制器的支持添加到program.cs文件中。您需要:
builder . Services . AddControllers ( ) ; // ControllersWithView if you need Views
// and
app . MapControllers ( ) ;一旦到位,您就應該能夠創建一個控制器文件夾,並((可選))一個視圖文件夾,並且一切都應按預期工作。就我個人而言,我發現Razor頁面比控制器和視圖要好得多,因此,如果您還沒有完全研究剃須刀頁面,則在選擇視圖之前,您可能想現在就這樣做。
您需要在program.cs文件中添加對Razor頁面的支持。您需要:
builder . Services . AddRazorPages ( ) ;
// and
app . MapRazorPages ( ) ;然後,您只需在項目的根部添加一個頁面夾即可從那裡添加。
要根據此存儲庫開始,您需要在本地獲得副本。您有三個選擇:叉子,克隆或下載。大多數情況下,您可能只想下載。
您應該下載存儲庫,取消封鎖zip文件,然後將其提取到新文件夾中,如果您只想使用該項目,或者希望將其用作應用程序的起點。
只有在您打算提交拉動請求時,才應該分配此存儲庫。或者,如果您想將存儲庫快照的副本保留在您自己的GitHub帳戶中。
如果您是貢獻者之一,並且可以訪問它,則應克隆此存儲庫。否則,您可能想要其他選項之一。
您不需要這樣做才能使用此模板,但是如果您希望在基礎架構項目中正確設置遷移,則在運行遷移命令時需要指定該項目名稱。
在Visual Studio中,打開軟件包管理器控制台,然後運行Add-Migration InitialMigrationName -StartupProject Your.ProjectName.Web -Context AppDbContext -Project Your.ProjectName.Infrastructure 。
在帶有CLI的終端中,命令相似。從Web項目目錄中運行此內容:
dotnet ef migrations add MIGRATIONNAME - c AppDbContext - p .. / Your.ProjectName.Infrastructure / Your.ProjectName.Infrastructure.csproj - s Your.ProjectName.Web.csproj - o Data / Migrations要使用sqlserver,請更改options.UseSqlite(connectionString)); to options.UseSqlServer(connectionString));在Your.ProjectName.Infrastructure.StartupSetup文件中。還要記住將SqliteConnection替換為Your.ProjectName.Web.Program文件中的DefaultConnection ,該文件指向您的數據庫服務器。
要更新數據庫,請使用Web Project文件夾中使用此命令(用項目的名稱替換Clean.Architecture ):
dotnet ef database update - c AppDbContext - p .. / Clean .Architecture.Infrastructure / Clean .Architecture.Infrastructure.csproj - s Clean .Architecture.Web.csproj該存儲庫的目的是提供一個基本的解決方案結構,該結構可用於構建域驅動設計(DDD)基於.NET Core的基於域驅動的設計(DDD)。在此處了解有關這些主題的更多信息:
如果您習慣於單個項目或遵循傳統UI->業務層 - >數據訪問層“ n -Tier”體系結構的一組項目構建應用程序,我建議您查看這兩個課程(理想情況下是在DDD基礎之前):
史蒂夫·史密斯(Steve Smith)還維護了Microsoft的參考應用程序Eshoponweb及其相關的免費電子書。在這裡查看它們:
請注意,該項目和存儲庫的目標不是提供示例或參考應用程序。它只是成為一個模板,但是有足夠的零件向您展示您在設置實際解決方案時所屬的位置。而不是無用的“ class1.cs”,有一些真實的類。一旦您了解它們為什麼在那裡,以及您應該將它們放置在哪裡,請刪除它們。如果您要尋找的話, /sample文件夾中有一個示例應用程序。
我已經使用此啟動器套件來使用域驅動的設計概念和模式來教授ASP.NET核心的基礎知識(從ASP.NET Core仍在預發行中時開始)。通常,在Devintersection之類的活動(或私人現場講習班)之前,我為希望通過最新的開發技術和技術加快其團隊的公司來教一個或兩天的動手研討會。如果您需要有關即將舉行的研討會的信息,請隨時與我聯繫。
該解決方案模板的目的是為新項目提供相當簡單的入門套件。它不包括特定企業應用程序可能受益的所有可能的框架,工具或功能。它對數據訪問等技術選擇的選擇植根於使用Microsoft技術堆棧的大多數商業軟件開發人員最常見的技術。它(當前)不包括對記錄,監視或分析等諸如諸如的大量支持,儘管這些都可以輕鬆添加。以下是它包含的技術依賴性以及為什麼選擇它們的列表。其中大多數可以輕鬆地換成您選擇的技術,因為該體系結構的性質是支持模塊化和封裝。
用戶輸入的驗證是所有軟件應用程序的要求。問題是,以簡潔而優雅的方式實施它有意義?該解決方案模板包括4個單獨的項目,每個項目都可能負責執行驗證以及執行業務不變性(給定驗證已經發生的驗證,通常是為例外)。
域模型本身通常應依靠面向對象的設計,以確保其始終處於一致的狀態。它利用封裝並限制了公共狀態突變訪問來實現這一目標,並假定已通過其傳遞給它的任何參數已經得到驗證,因此在大多數情況下,零值或其他不當值會產生異常,而不是驗證結果。
用例 /應用程序項目包括系統支持的所有命令和查詢。它經常負責驗證自己的命令和查詢對象。這是使用MediaTR行為或其他一些管道使用的責任模式鏈最容易完成的。
Web項目包括所有API端點,其中包括其自己的請求和響應類型,按照reper模式。 Butdendpoints庫包括對請求類型的FulentValidation進行驗證的內置支持。這也是執行輸入驗證的自然場所。
在API端點內進行驗證,然後在用例級別上再次發生驗證可能被認為是冗餘的。在兩個地方添加基本相同的驗證,一個用於API請求,另一個是發送給用例處理程序的消息的權衡。在防禦性編碼之後,在兩個地方添加驗證通常是有意義的,因為開銷很小,心靈的平靜和更大的應用魯棒性通常值得。
核心項目是乾淨建築設計的中心,所有其他項目依賴性都應指向它。因此,它的外部依賴性很少。核心項目應包括域模型,包括以下內容:
您可以了解有關這些模式以及如何在此處應用它們的更多信息:
一個可選的項目,我將其包括在內,因為許多人都要求它,並且刪除比以後更容易刪除。這通常也稱為應用程序或應用程序服務層。使用CQRS遵循命令和查詢(我考慮使用Commands和Queries文件夾,但覺得它添加的文件夾很少 - 每個實際命令或查詢的文件夾就足夠了,而沒有額外的嵌套就足夠了)。命令突變域模型,因此應始終將存儲庫抽像用於其數據訪問(存儲庫是一個獲取和持續域模型類型的方式)。查詢是閱讀的,因此不需要使用存儲庫模式,而是可以使用最方便的任何查詢服務或方法。
由於用例設置為依賴核心,並且不依賴基礎架構,因此仍然需要為其數據訪問定義抽象。它可以使用規格之類的東西,有時可以幫助封裝查詢邏輯以及結果類型映射。但是它不必使用存儲庫/規範 - 如果這是獲取數據的最有效方法,它只能發出SQL查詢或調用存儲過程。
Although this is an optional project to include (without it, your API endpoints would just work directly with the domain model or query services), it does provide a nice UI-ignorant place to add automated tests, and lends itself toward applying policies for cross-cutting concerns using a Chain of Responsibility pattern around the message handlers (for things like validation, caching, auth, logging, timing, etc.).該模板包含一個用於記錄的示例,該示例位於共享Kernel Nuget軟件包中。
您應用程序對外部資源的大多數依賴性應在基礎架構項目中定義的類中實現。這些類應實現核心定義的接口。如果您有一個非常大的項目具有許多依賴關係,那麼擁有多個基礎架構項目(例如Infrastructure.data)可能是有意義的,但是對於大多數項目,一個帶有文件夾的基礎架構項目都可以正常工作。該模板包含數據訪問和域事件實現,但是您還將在此項目中添加電子郵件提供商,文件訪問,Web API客戶端等諸如諸如電子郵件提供商,文件訪問,Web API客戶端等,因此他們不會將耦合添加到您的核心或UI項目中。
應用程序的輸入點是ASP.NET Core Web項目(或Aspirehost項目,該項目又加載了Web項目)。這實際上是一個控制台應用程序,在Program.cs中具有public static void Main方法。它利用butdendpoint和reper模式組織其API端點。
共享內核用於共享有限上下文之間的共同元素。這是一個DDD術語,但是許多組織利用“常見”項目或軟件包用於在幾個應用程序之間共享的事物。
如果您需要在多個有限上下文之間共享代碼(請參閱DDD基本原理),我建議您創建一個單獨的共享kernel項目和解決方案。我進一步建議將其作為Nuget軟件包(最有可能在您的組織中私下)發布,並由需要它的項目稱為Nuget依賴。
以前,該項目包括一個共享業務的項目。但是,由於上述原因,我將其製作了一個單獨的軟件包Ardalis.sharedkernel,當您使用此模板時,您應該用自己的替換。
如果您想查看共享kernel軟件包的另一個示例,那麼我在更新的Pluralsight DDD課程中使用的一個示例在Nuget上。
可以根據測試(單位,功能,集成,性能等)的類型組織測試項目,也可以通過他們正在測試的項目(核心,基礎架構,Web)或兩者進行組織。對於這個簡單的入門套件,測試項目是根據測試的類型組織的,該測試具有單位,功能和集成測試項目。功能測試是一種特殊的集成測試,可以對Web項目的API進行皮下測試,而無需實際託管真實的網站或越過網絡。我創建了一堆測試助手,以使這類測試更短,更易於維護。
該解決方案模板內置了代碼,以支持一些常見模式,尤其是域驅動的設計模式。這是其中一些工作方式的簡要概述。
域事件是將操作與實施的觸發觸發的絕佳模式。這是從域內實體中特別有用的,因為事件的處理程序可以具有依賴關係,而實體本身通常不具有依賴關係。在示例中,您可以使用ToDoItem.MarkComplete()方法看到此操作。以下序列圖說明了通過Web API端點標記項目完成時如何使用事件及其處理程序。
