Ordnerstruktur für .NET Projekte
Dieser Artikel behandelt den grundlegenden, empfohlenen Aufbau der Ordnerstukturen von .NET Anwendungen.
In den seltensten Fällen besteht eine Anwendung oder eine Bibliothek einzig und alleine aus einem einzigen C# Projekt; sondern im Endeffekt aus mehreren Projekten.
Daher behandelt dieser Artikel auch den am meisten vorhanden Fall, dass mehrere Projekte in einer Solution zusammen gefasst werden.
Microsoft selbst gibt keine konkreten Vorgaben an, wie entsprechende Ordnerstrukturen auszusehen haben, sondern verweisen auf den "üblichen Umgang" mit Namespaces und der entsprechenden Trennung von Quellcode hinweg über mehrere Visual Studio Projekte.
Die Inhalte beziehen sich dahingehend auf weit verbreitete Open Source Commitments sowie Best Practises als Orientierungshilfe.
Die empfohlene Ordnerstruktur
$/
artifacts/ Ordner für den Build-Output (optional)
build/ Build Scripts
docs/ Dokumentationen (meist Markdown-Dateien) (optional)
lib/ Assemblies, die **nicht** in NuGet-Paketen verteilt werden können
packages/ NuGet-Pakete (optional, da diese normalerweise nicht im Projekt selbst abgelegt werden, sondern von einem NuGet Feed kommen)
samples/ Beispiel-Projekte
src/ Produkt Quellcode, hier befinden sich die csproj-Dateien der C# Projekte
tests/ Quellcode für Tests Projekte
wiki/ Wiki als optionale Alternative für docs/
.editorconfig Code Style Definitions
.gitignore
.gitattributes
build.cmd Build-Script unter Windows (optional)
build.sh Build-Script unter *Unix (optional)
global.json
LICENSE
NuGet.Config
README.md
{solution}.sln
Warum diese Struktur?
Wie jedes Muster, hat sich auch diese Struktur mit der Zeit und durch unzählige Projekte sowie Quellen als vorteilhaft herauskristallisiert und gilt seit David Fowlers (ein Architekt von Microsoft für u.a. ASP.NET) Gist .NET project structure, indem diese Struktur vermutlich erstmals niedergeschrieben wurde, als de-facto Standard.
In den Kommentaren zu diesem Gist sammelte er eine Menge an Feedback sowie Best Practises und hat dabei auch andere Ökosysteme wie JavaScript, TypeScript und Java einfliessen lassen.
Sie garantiert, dass alle notwendigen Inhalte innerhalb dieser Struktur existieren und es keine weiteren Referenzen auf irgendwelche übergeordneten Ordner (zB. Assembly-Verweise) notwendig sind.
Der Aufbau ist sehr allgemein und deckt verschiedene Anforderungen ab, die prinzipiell nicht in jedem Umfeld vorhanden sein müssen; werden beispielsweise keine Beispiele/Samples bereitgestellt, dann existiert entsprechend auch der samples-Ordner nicht bzw. kann dieser weggelassen werden. Einheitliche Projektstrukturen sind v.a. in der Open-Source Umgebung sehr vorteilhaft, da sich ein potentieller Contributor schnell im Projekt zurechtfindet und sich nicht erst durch die Projekt-Organisation wühlen muss.
Wie bei jedem Muster muss die Struktur daher nicht 1:1 übernommen werden, sondern bildet die Grundlage und einen Anhaltspunkt für einen invidiuellen Aufbau.
Ein weiterer Vorteil dieser Struktur ist, dass viele Tools (ob bewusst oder unbewusst) in der .NET Welt abgestimmt sind / passen, zum Beispiel die .NET CLI.
Entstanden zusammen mit gfoidl.
Historie:
2021-01-02: Veröffentlichung
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code