Ein Ausgangspunkt für saubere Architektur mit ASP.NET Core. Clean Architecture ist nur die neueste in einer Reihe von Namen für die gleiche lose gekoppelte, abhängige Architektur. Sie werden es auch als hexagonale, Ports und Adapter oder Zwiebelarchitektur als namens hexagonisch empfinden.
Erfahren Sie mehr über Clean Architecture und diese Vorlage in NimblePros 'Einführung in Clean Architecture Course. Verwenden Sie den Code Ardalis, um 20%zu sparen.
Diese Architektur wird im DDD Fundamentals -Kurs von Steve Smith und Julie Lerman verwendet.
? Wenden Sie sich an Steve's Company, NimblePros, für Clean Architecture oder DDD -Schulungs- und/oder Implementierungsunterstützung für Ihr Team.
Erfahren Sie, wie Sie saubere Architektur von NimblePros -Trainern Sarah "Sadukie" Dutkiewicz und Steve "Ardalis" Smith implementieren.
Wenn Sie dieses Projekt mögen oder verwenden, um Ihre Lösung zu lernen oder zu starten, geben Sie ihm bitte einen Stern. Danke!
Oder wenn Sie sich wirklich großzügig fühlen, unterstützen wir jetzt Github -Sponsoring - siehe die Schaltfläche oben.
Ich kann mir bekannt geben, dass der Foss-Fonds von Amazon AWS beschlossen hat, dieses Projekt ein 12-monatiges Sponsoring zu vergeben. Vielen Dank und danke an alle meine anderen vergangenen und aktuellen Sponsoren!
Standardmäßig verwendet die Site HTTPS und erwartet, dass Sie ein selbstsigniertes Entwicklerzertifikat für die Verwendung von Localhost verwenden. Wenn Sie einen Fehler mit Chrome erhalten, finden Sie diese Antwort für Anweisungen zur Minderung.
Der Hauptzweig verwendet jetzt .NET 9 . Dies entspricht der Nuget -Paketversion 10.x. Frühere Versionen sind verfügbar - siehe unsere Veröffentlichungen.
Um diese Vorlage zu verwenden, gibt es einige Optionen:
dotnet new (empfohlen)Installieren Sie zunächst die Vorlage von Nuget (https://www.nuget.org/packages/ardalis.cleanarchitecture.template/):
dotnet new install Ardalis.CleanArchitecture.Template Sie können verfügbare Optionen sehen, indem Sie den Befehl mit der -? Option:
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 Sie sollten die Vorlage in der Liste der Vorlagen aus dotnet new list nach dieser Installation sehen. Suchen Sie nach "ASP.NET Clean Architecture Solution" mit kurzem Namen von "Clean-Arch".
Navigieren Sie zu dem übergeordneten Verzeichnis, in dem der Ordner der Lösung erstellt werden soll.
Führen Sie diesen Befehl aus, um die Lösungsstruktur in einem Unterordner zu erstellen Your.ProjectName
dotnet new clean-arch -o Your.ProjectName
Das Verzeichnis Your.ProjectName und die Lösungsdatei werden erstellt, und im Inneren werden alle Ihren neuen Lösungsinhalt ordnungsgemäß genannt und bereit zum Ausführen/Test!
Beispiel: 
Vielen Dank an @dahlSailrunner für Ihre Hilfe, um dies zum Laufen zu bringen!
Bekannte Probleme :
Ab Version 9 enthält diese Lösungsvorlage nur Unterstützung für API -Endpunkte mithilfe der FastendPoints -Bibliothek. Wenn Sie meine Apiendpoints Library, Rasierseiten und/oder Controller verwenden möchten, können Sie die letzte Vorlage verwenden, die sie enthielt, Version 7.1. Alternativ werden diese Vorlage nach der Installation problemlos hinzugefügt.
Um Ardalis.apiendpoints anstelle von (oder zusätzlich zu) Fastendpoints zu verwenden, fügen Sie einfach die Referenz hinzu und verwenden Sie die Basisklassen aus der Dokumentation.
dotnet add package Ardalis.ApiEndpointsSie müssen die Controller zur Datei Programm.cs unterstützen. Sie brauchen:
builder . Services . AddControllers ( ) ; // ControllersWithView if you need Views
// and
app . MapControllers ( ) ;Sobald diese vorhanden sind, sollten Sie in der Lage sein, einen Controller -Ordner und (optional) einen Ansichtsordner zu erstellen, und alles sollte wie erwartet funktionieren. Persönlich finde ich Rasierseiten, die viel besser sind als Controller und Ansichten. Wenn Sie also nicht vollständig Rasierseiten untersucht haben, möchten Sie dies möglicherweise richtig tun, bevor Sie Ansichten auswählen.
Sie müssen der Datei program.cs -Datei Unterstützung für Rasiermesserseiten hinzufügen. Sie brauchen:
builder . Services . AddRazorPages ( ) ;
// and
app . MapRazorPages ( ) ;Dann fügen Sie einfach einen Seitenordner in die Wurzel des Projekts hinzu und gehen von dort aus.
Um mit diesem Repository zu beginnen, müssen Sie eine Kopie vor Ort erhalten. Sie haben drei Optionen: Gabel, Klon oder Download. Meistens möchten Sie wahrscheinlich nur herunterladen.
Sie sollten das Repository herunterladen , die ZIP -Datei entsperren und in einen neuen Ordner extrahieren, wenn Sie nur mit dem Projekt abspielen möchten oder es als Ausgangspunkt für eine Anwendung verwenden möchten.
Sie sollten dieses Repository nur dann aufgeben , wenn Sie vorhaben, eine Pull -Anfrage einzureichen. Oder wenn Sie eine Kopie eines Schnappschusss des Repositorys in Ihrem eigenen GitHub -Konto beibehalten möchten.
Sie sollten dieses Repository klonen, wenn Sie einer der Mitwirkenden sind und Zugang dazu erhalten. Andernfalls möchten Sie wahrscheinlich eine der anderen Optionen.
Sie sollten dies nicht tun müssen, um diese Vorlage zu verwenden. Wenn Sie jedoch im Infrastrukturprojekt die Migrationen ordnungsgemäß einrichten möchten, müssen Sie diesen Projektnamen angeben, wenn Sie den Befehl migrationen ausführen.
Öffnen Sie in Visual Studio die Paket -Manager -Konsole und führen Sie Add-Migration InitialMigrationName -StartupProject Your.ProjectName.Web -Context AppDbContext -Project Your.ProjectName.Infrastructure .
In einem Terminal mit der CLI ist der Befehl ähnlich. Führen Sie dies aus dem Webprojektverzeichnis aus:
dotnet ef migrations add MIGRATIONNAME - c AppDbContext - p .. / Your.ProjectName.Infrastructure / Your.ProjectName.Infrastructure.csproj - s Your.ProjectName.Web.csproj - o Data / Migrations Um SQLServer zu verwenden, ändern Sie options.UseSqlite(connectionString)); an options.UseSqlServer(connectionString)); In der Datei Your.ProjectName.Infrastructure.StartupSetup . Denken Sie auch daran, die SqliteConnection durch DefaultConnection in der Datei Your.ProjectName.Web.Program zu ersetzen, die auf Ihren Datenbankserver verweist.
Um die Datenbank zu aktualisieren, verwenden Sie diesen Befehl aus dem Web -Projektordner ( Clean.Architecture mit dem Namen Ihres Projekts ersetzen):
dotnet ef database update - c AppDbContext - p .. / Clean .Architecture.Infrastructure / Clean .Architecture.Infrastructure.csproj - s Clean .Architecture.Web.csprojDas Ziel dieses Repositorys ist es, eine grundlegende Lösungsstruktur bereitzustellen, mit der DDD-Basis (DODD) oder einfach gut ausgestattete, solide Anwendungen mit .NET Core erstellt werden können. Erfahren Sie hier mehr über diese Themen:
Wenn Sie es gewohnt sind, Anwendungen als Single -Project oder als eine Reihe von Projekten zu erstellen, die der herkömmlichen UI -> Business Layer -> Datenzugriffsschicht "N -Tier" -Scharchitektur folgen, empfehle ich Ihnen, diese beiden Kurse (idealerweise vor DDD -Grundlagen) zu lesen:
Steve Smith unterhält auch die Referenzanwendung von Microsoft, Eshoponweb und das zugehörige kostenlose E -Book. Schauen Sie sich sie hier an:
Beachten Sie, dass das Ziel dieses Projekts und des Repositorys nicht darin besteht, eine Beispiel- oder Referenzanwendung bereitzustellen. Es soll nur eine Vorlage sein, aber mit genügend Teilen, um Ihnen zu zeigen, wo die Dinge gehören, wenn Sie Ihre tatsächliche Lösung einrichten. Anstelle von nutzlosen "class1.cs" gibt es ein paar echte Klassen. Löschen Sie sie, sobald Sie verstehen, warum sie da sind und wo Sie Ihre eigenen, ähnlichen Dateien einsetzen sollten. Es gibt eine Beispielanwendung im /sample , wenn Sie danach suchen.
Ich habe dieses Starter-Kit verwendet, um die Grundlagen des ASP.NET-Kerns unter Verwendung von domänengesteuerten Designkonzepten und -Mustern seit einiger Zeit zu lehren (beginnend, wenn ASP.NET CORE noch in der Vorabveröffentlichung war). Normalerweise unterrichte ich einen ein- oder zweitägigen praktischen Workshop vor Veranstaltungen wie Devintersection oder private Workshops vor Ort für Unternehmen, die ihre Teams mit den neuesten Entwicklungstechnologien und -techniken auf den Laufenden bringen möchten. Sie können mich gerne kontaktieren, wenn Sie Informationen zu bevorstehenden Workshops wünschen.
Das Ziel dieser Lösungsvorlage ist es, ein ziemlich nacktes Starter-Kit für neue Projekte bereitzustellen. Es enthält nicht jedes mögliche Framework, Tool oder eine Funktion, von der eine bestimmte Unternehmensanwendung möglicherweise profitieren. Die Auswahltechnik für Dinge wie den Datenzugriff basiert auf der häufigsten und zugänglichen Technologie für die meisten Business -Software -Entwickler, die den Technologiestack von Microsoft verwenden. Es beinhaltet nicht (derzeit) eine umfassende Unterstützung für Dinge wie Protokollierung, Überwachung oder Analyse, obwohl diese alle leicht hinzugefügt werden können. Im Folgenden finden Sie eine Liste der technologischen Abhängigkeiten und warum sie ausgewählt wurden. Die meisten davon können leicht gegen Ihre Wahltechnologie ausgetauscht werden, da die Art dieser Architektur die Unterstützung von Modularität und Kapselung besteht.
Die Validierung der Benutzereingabe ist eine Anforderung aller Softwareanwendungen. Die Frage ist, wo ist es sinnvoll, es präzise und elegant zu implementieren? Diese Lösungsvorlage enthält 4 separate Projekte, von denen jedes für die Durchführung der Validierung sowie für die Durchsetzung von Geschäftsinvarianten verantwortlich ist (die bei der Validierung bereits in der Regel als Ausnahmen modelliert werden).
Das Domänenmodell selbst sollte sich im Allgemeinen auf objektorientiertes Design verlassen, um sicherzustellen, dass es immer in einem konsistenten Zustand ist. Es nutzt die Einkapselung und begrenzt den Zugang zum öffentlichen Staat, um dies zu erreichen, und es wird davon ausgegangen, dass alle an sie verabschiedeten Argumente bereits validiert wurden, so dass Null oder andere unsachgemäße Werte in den meisten Fällen keine Validierungsergebnisse ergeben.
Das Anwendungsfälle / Anwendungsprojekt enthält die Menge aller Befehle und fragt das System an. Es ist häufig verantwortlich für die Validierung seines eigenen Befehls und der Abfrageobjekte. Dies kann am einfachsten mit einer Kette von Verantwortungsmuster über Meditr -Verhalten oder eine andere Pipeline durchgeführt werden.
Das Webprojekt enthält alle API -Endpunkte, die ihre eigenen Anfrage- und Antworttypen entsprechen, die dem REP -Muster folgen. Die FastendPoints-Bibliothek umfasst eine integrierte Unterstützung für die Validierung unter Verwendung von FluentValidation an den Anforderungsarten. Dies ist auch ein natürlicher Ort, um die Eingabevalidierung durchzuführen.
Die Validierung tritt sowohl innerhalb der API -Endpunkte als auch wieder auf der Anwendungsfallebene als redundant an. Es gibt Kompromisse beim Hinzufügen der im Wesentlichen die gleiche Validierung an zwei Stellen, eines für API -Anfragen und eine für Nachrichten, die an Anwendungsfallhandler gesendet werden. Nach der defensiven Codierung ist es oft sinnvoll, an beiden Orten Validierung hinzuzufügen, da der Overhead minimal ist und der Seelenfrieden und die größere Anwendungsrobustheit oft wert sind.
Das Kernprojekt ist das Zentrum des Clean Architecture Design, und alle anderen Projektabhängigkeiten sollten darauf hinweisen. Daher hat es nur sehr wenige externe Abhängigkeiten. Das Kernprojekt sollte das Domänenmodell einschließlich Dingen wie:
Weitere Informationen zu diesen Mustern und wie Sie sie hier anwenden:
Ein optionales Projekt, das ich beigefügt habe, weil viele Leute es forderten und es einfacher zu entfernen ist, als später hinzuzufügen. Dies wird auch häufig als Anwendungs- oder Anwendungsdiensteschicht bezeichnet. Das Anwendungsfällenprojekt ist nach CQRs in Befehle und Abfragen organisiert (ich habe überlegt, Ordner für Commands und Queries zu haben, aber es fühlte sich nur wenig hinzugefügt - die Ordner pro tatsächlicher Befehl oder Abfrage sind ausreichend ohne zusätzliche Nistung). Befehle mutieren das Domänenmodell und sollte daher immer Repository -Abstraktionen für ihren Datenzugriff verwenden (Repositories sind, wie man Domänenmodelltypen abreißt und fortsetzt). Abfragen sind readonly und müssen daher das Repository -Muster nicht verwenden , sondern können den Abfragedienst oder den Ansatz verwenden, der am bequemsten ist.
Da das Anwendungsfällenprojekt so eingerichtet ist, dass sie vom Kern abhängen und nicht von der Infrastruktur abhängen, müssen für den Datenzugriff auch Abstraktionen definiert werden. Und es kann Dinge wie Spezifikationen verwenden, die manchmal dazu beitragen können, die Abfragelogik sowie die Zuordnung von Ergebnisstypen zu verkörpern. Es muss jedoch nicht Repository/Spezifikation verwendet werden - es kann nur eine SQL -Abfrage ausstellen oder eine gespeicherte Prozedur aufrufen, wenn dies der effizienteste Weg ist, um die Daten zu erhalten.
Obwohl dies ein optionales Projekt ist, das einbezogen werden soll (ohne sie würden Ihre API-Endpunkte direkt mit dem Domänenmodell oder den Abfragediensten zusammenarbeiten), bietet es einen schönen Ui-Ignoranten-Ort, um automatisierte Tests hinzuzufügen, und verleiht sich für die Anwendung von Richtlinien für Kreuzungsbedenken, indem Sie eine Kette des Verantwortungsmusters um die Botschaftshandler (für Dinge wie Validierung, Caching, Authelling, Authelling, Authelling, Lokging, Lokging, Lokging, Lokging, Zeiteinziele usw.). Die Vorlage enthält ein Beispiel hierfür für die Protokollierung, das sich im SharedKernel Nuget -Paket befindet.
Die meisten Abhängigkeiten Ihrer Anwendung von externen Ressourcen sollten in Klassen implementiert werden, die im Infrastrukturprojekt definiert sind. Diese Klassen sollten im Kern definierte Schnittstellen implementieren. Wenn Sie ein sehr großes Projekt mit vielen Abhängigkeiten haben, kann es sinnvoll sein, mehrere Infrastrukturprojekte (z. Die Vorlage enthält Implementierungen des Datenzugriffs und der Domänenereignis. Sie würden jedoch auch Dinge wie E -Mail -Anbieter, Dateizugriff, Web -API -Clients usw. hinzufügen, sodass sie Ihrem Kern- oder UI -Projekt keine Kopplung hinzufügen.
Der Einstiegspunkt der Anwendung ist das ASP.NET -Kern -Webprojekt (oder möglicherweise das Aspirehost -Projekt, das wiederum das Webprojekt lädt). Dies ist eigentlich eine Konsolenanwendung mit einer public static void Main in Program.cs . Es nutzt Fastendpoints und das Repr -Muster, um seine API -Endpunkte zu organisieren.
Ein gemeinsamer Kernel wird verwendet, um gemeinsame Elemente zwischen begrenzten Kontexten zu teilen. Es ist ein DDD -Begriff, aber viele Organisationen nutzen "gemeinsame" Projekte oder Pakete für Dinge, die nützlich sind, um zwischen mehreren Anwendungen zu teilen.
Ich empfehle, ein separates SharedKernel -Projekt und eine separate Lösung zu erstellen, wenn Sie Code zwischen mehreren begrenzten Kontexten teilen müssen (siehe DDD -Grundlagen). Ich empfehle ferner, dies als Nuget -Paket (höchstwahrscheinlich privat in Ihrer Organisation) veröffentlicht zu werden und als NUGET -Abhängigkeit von diesen Projekten zu bezeichnen ist.
Zuvor wurde ein Projekt für SharedKernel in dieses Projekt aufgenommen. Aus den oben genannten Gründen habe ich es jedoch zu einem separaten Paket, Ardalis.Sharedkernel, gemacht, den Sie durch die Verwendung dieser Vorlage durch Ihre eigenen ersetzen sollten .
Wenn Sie ein weiteres Beispiel für ein SharedKernel -Paket sehen möchten, befindet sich das, das ich in meinem aktualisierten Pluralsight -DDD -Kurs verwende, hier auf Nuget.
Testprojekte können basierend auf der Art des Tests (Einheit, Funktion, Integration, Leistung usw.) oder nach dem Projekt (Kern, Infrastruktur, Web) oder beides organisiert werden. Für dieses einfache Starter -Kit werden die Testprojekte basierend auf der Art des Tests mit Einheiten-, Funktions- und Integrationstestprojekten organisiert, die in dieser Lösung vorhanden sind. Funktionstests sind eine spezielle Art von Integrationstest, die subkutane Tests der APIs des Webprojekts durchführen, ohne tatsächlich eine echte Website zu hosten oder das Netzwerk durchzuführen. Ich habe eine Reihe von Testhelfern erstellt, um diese Art von Tests kürzer und leichter aufrechtzuerhalten.
In dieser Lösungsvorlage wird Code integriert, um einige gemeinsame Muster zu unterstützen, insbesondere domänengesteuerte Designmuster. Hier ist ein kurzer Überblick darüber, wie einige von ihnen funktionieren.
Domänenereignisse sind ein großartiges Muster für die Entkopplung eines Auslösers für einen Betrieb aus seiner Implementierung. Dies ist besonders von innerhalb von Domänenunternehmen nützlich, da die Handler der Ereignisse Abhängigkeiten haben können, während die Entitäten selbst normalerweise dies nicht tun. In der Stichprobe können Sie dies in Aktion mit der Methode ToDoItem.MarkComplete() sehen. Das folgende Sequenzdiagramm zeigt, wie das Ereignis und sein Handler verwendet werden, wenn ein Element über einen Web -API -Endpunkt komplett markiert wird.
