$npx -y skills add Aaronontheweb/dotnet-skills --skill project-structureModern .NET project structure including .slnx solution format, Directory.Build.props, central package management, SourceLink, version management with RELEASE_NOTES.md, and SDK pinning with global.json.
| 1 | # .NET Project Structure and Build Configuration |
| 2 | |
| 3 | ## When to Use This Skill |
| 4 | |
| 5 | Use this skill when: |
| 6 | - Setting up a new .NET solution with modern best practices |
| 7 | - Configuring centralized build properties across multiple projects |
| 8 | - Implementing central package version management |
| 9 | - Setting up SourceLink for debugging and NuGet packages |
| 10 | - Automating version management with release notes |
| 11 | - Pinning SDK versions for consistent builds |
| 12 | |
| 13 | ## Related Skills |
| 14 | |
| 15 | - **`dotnet-local-tools`** - Managing local .NET tools with dotnet-tools.json |
| 16 | - **`microsoft-extensions-configuration`** - Configuration validation patterns |
| 17 | |
| 18 | --- |
| 19 | |
| 20 | ## Solution File Format (.slnx) |
| 21 | |
| 22 | The `.slnx` format is the modern XML-based solution file format introduced in .NET 9. It replaces the traditional `.sln` format. |
| 23 | |
| 24 | ### Benefits Over Traditional .sln |
| 25 | |
| 26 | | Aspect | .sln (Legacy) | .slnx (Modern) | |
| 27 | |--------|---------------|----------------| |
| 28 | | Format | Custom text format | Standard XML | |
| 29 | | Readability | GUIDs, cryptic syntax | Clean, human-readable | |
| 30 | | Version control | Hard to diff/merge | Easy to diff/merge | |
| 31 | | Editing | IDE required | Any text editor | |
| 32 | |
| 33 | ### Version Requirements |
| 34 | |
| 35 | | Tool | Minimum Version | |
| 36 | |------|-----------------| |
| 37 | | .NET SDK | 9.0.200 | |
| 38 | | Visual Studio | 17.13 | |
| 39 | | MSBuild | Visual Studio Build Tools 17.13 | |
| 40 | |
| 41 | **Note:** Starting with .NET 10, `dotnet new sln` creates `.slnx` files by default. In .NET 9, you must explicitly migrate or specify the format. |
| 42 | |
| 43 | ### Example .slnx File |
| 44 | |
| 45 | ```xml |
| 46 | <Solution> |
| 47 | <Folder Name="/build/"> |
| 48 | <File Path="Directory.Build.props" /> |
| 49 | <File Path="Directory.Packages.props" /> |
| 50 | <File Path="global.json" /> |
| 51 | <File Path="NuGet.Config" /> |
| 52 | <File Path="README.md" /> |
| 53 | </Folder> |
| 54 | <Folder Name="/src/"> |
| 55 | <Project Path="src/MyApp/MyApp.csproj" /> |
| 56 | <Project Path="src/MyApp.Core/MyApp.Core.csproj" /> |
| 57 | </Folder> |
| 58 | <Folder Name="/tests/"> |
| 59 | <Project Path="tests/MyApp.Tests/MyApp.Tests.csproj" /> |
| 60 | </Folder> |
| 61 | </Solution> |
| 62 | ``` |
| 63 | |
| 64 | ### Migrating from .sln to .slnx |
| 65 | |
| 66 | Use the `dotnet sln migrate` command to convert existing solutions: |
| 67 | |
| 68 | ```bash |
| 69 | # Migrate a specific solution file |
| 70 | dotnet sln MySolution.sln migrate |
| 71 | |
| 72 | # Or if only one .sln exists in the directory, just run: |
| 73 | dotnet sln migrate |
| 74 | ``` |
| 75 | |
| 76 | **Important:** Do not keep both `.sln` and `.slnx` files in the same repository. This causes issues with automatic solution detection and can lead to sync problems. After migration, delete the old `.sln` file. |
| 77 | |
| 78 | You can also migrate in Visual Studio: |
| 79 | 1. Open the solution |
| 80 | 2. Select the Solution in Solution Explorer |
| 81 | 3. Go to **File > Save Solution As...** |
| 82 | 4. Change "Save as type" to **Xml Solution File (*.slnx)** |
| 83 | |
| 84 | ### Creating a New .slnx Solution |
| 85 | |
| 86 | ```bash |
| 87 | # .NET 10+: Creates .slnx by default |
| 88 | dotnet new sln --name MySolution |
| 89 | |
| 90 | # .NET 9: Specify the format explicitly |
| 91 | dotnet new sln --name MySolution --format slnx |
| 92 | |
| 93 | # Add projects (works the same for both formats) |
| 94 | dotnet sln add src/MyApp/MyApp.csproj |
| 95 | ``` |
| 96 | |
| 97 | ### Recommendation |
| 98 | |
| 99 | **If you're using .NET 9.0.200 or later, migrate your solutions to .slnx.** The benefits are significant: |
| 100 | - Dramatically fewer merge conflicts (no random GUIDs changing) |
| 101 | - Human-readable and editable in any text editor |
| 102 | - Consistent with modern `.csproj` format |
| 103 | - Better diff/review experience in pull requests |
| 104 | |
| 105 | --- |
| 106 | |
| 107 | ## Directory.Build.props |
| 108 | |
| 109 | `Directory.Build.props` provides centralized build configuration that applies to all projects in a directory tree. Place it at the solution root. |
| 110 | |
| 111 | ### Complete Example |
| 112 | |
| 113 | ```xml |
| 114 | <Project> |
| 115 | <!-- Metadata --> |
| 116 | <PropertyGroup> |
| 117 | <Authors>Your Team</Authors> |
| 118 | <Company>Your Company</Company> |
| 119 | <!-- Dynamic copyright year - updates automatically --> |
| 120 | <Copyright>Copyright © 2020-$([System.DateTime]::Now.Year) Your Company</Copyright> |
| 121 | <Product>Your Product</Product> |
| 122 | <PackageProjectUrl>https://github.com/yourorg/yourrepo</PackageProjectUrl> |
| 123 | <RepositoryUrl>https://github.com/yourorg/yourrepo</RepositoryUrl> |
| 124 | <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression> |
| 125 | <PackageTags>your;tags;here</PackageTags> |
| 126 | </PropertyGroup> |
| 127 | |
| 128 | <!-- C# Language Settings --> |
| 129 | <PropertyGroup> |
| 130 | <LangVersion>latest</LangVersion> |
| 131 | <Nullable>enable</Nullable> |
| 132 | <ImplicitUsings>enable</ImplicitUsings> |
| 133 | <TreatWarningsAsErrors>true</TreatWarningsAsErrors> |
| 134 | <NoWarn>$(NoWarn);CS1591</NoWarn> <!-- Missing XML comments --> |
| 135 | </PropertyGroup> |
| 136 | |
| 137 | <!-- Version Management --> |
| 138 | <PropertyGroup> |
| 139 | <VersionPrefix>1.0.0</VersionPrefix> |
| 140 | <PackageReleaseNotes>See RELEASE_NOTES.md</PackageReleaseNotes> |
| 141 | </PropertyGroup> |
| 142 | |
| 143 | <!-- Target Framework Definitions (reusable properties) --> |
| 144 | <PropertyGroup> |
| 145 | <NetStandardLibVersion>netstandard2.0</NetStandardLibVersion> |
| 146 | <NetLibVersion>net8.0</NetLibVersion> |
| 147 | < |