Project Scaffolding¶
Root-level files that every solution starts with. They define the SDK, shared build settings, package versions, and code style once for all projects.
Layout¶
repo/
global.json
.editorconfig
.config/
dotnet-tools.json
src/
YourApp.slnx
Directory.Build.props
Directory.Packages.props
YourApp/
YourApp.Core/
Solution format: .slnx¶
Use the .slnx XML solution format. It is human-readable, diff-friendly, and avoids the GUID noise of .sln.
<Solution>
<Folder Name="/src/">
<Project Path="YourApp/YourApp.csproj" />
<Project Path="YourApp.Core/YourApp.Core.csproj" />
</Folder>
</Solution>
Directory.Build.props¶
Shared properties for every project in the tree.
<Project>
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>
Central Package Management¶
Versions live in Directory.Packages.props. Project files reference packages without versions.
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Akka" Version="1.5.0" />
<PackageVersion Include="xunit.v3" Version="1.0.0" />
</ItemGroup>
</Project>
Tip
Use dotnet add package / dotnet remove package rather than editing XML by hand. Use shared version properties for related packages that must move together.
global.json¶
Pin the SDK so every machine and CI runner builds with the same version.
.editorconfig¶
The .editorconfig defines code style and naming rules, enforced by dotnet format in CI.
Never modify .editorconfig to silence warnings
The file defines the project's rules. Fix the code to match it. Changing a rule to make a warning disappear defeats the purpose of having one.
Local tools¶
Declare tools in .config/dotnet-tools.json so everyone (and CI) uses the same versions.
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-stryker": { "version": "4.0.0", "commands": ["dotnet-stryker"] },
"dotnet-reportgenerator-globaltool": { "version": "5.3.0", "commands": ["reportgenerator"] }
}
}
Restore with dotnet tool restore. dotnet format ships with the SDK, so it needs no manifest entry.