Skip to content

Commit db35ac6

Browse files
committed
feat: Add comprehensive documentation for .NET scaffolding skills, including build properties, editorconfig, package management, solution formats, and project templates
1 parent ab063c2 commit db35ac6

6 files changed

Lines changed: 1007 additions & 0 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
name: dotnet-scaffold
3+
description: Use this skill when scaffolding new .NET solutions or projects, configuring shared build properties, setting up NuGet Central Package Management, enforcing code style with .editorconfig, or choosing between .sln and .slnx solution formats. Always trigger when users ask about dotnet new templates, multi-project solution layout, Directory.Build.props, Directory.Packages.props, .editorconfig, global.json, TreatWarningsAsErrors, LangVersion, or anything about organizing a .NET repository from scratch—even if they don't mention any of those file names explicitly.
4+
---
5+
6+
# .NET Scaffolding Skill
7+
8+
Use this skill to scaffold modern .NET solutions and projects correctly. The
9+
non-obvious parts are covered in the reference files below — read the relevant
10+
ones before generating or modifying any scaffolding files.
11+
12+
---
13+
14+
## Quick decision tree
15+
16+
| Question | Go to |
17+
|----------|-------|
18+
| Which `dotnet new` template to use? What options exist? | [references/templates.md](references/templates.md) |
19+
| Create or manage a solution file? sln vs slnx? | [references/solution.md](references/solution.md) |
20+
| Set properties that apply to all projects in the repo? | [references/build-props.md](references/build-props.md) |
21+
| Centralize NuGet versions in one place? | [references/packages-props.md](references/packages-props.md) |
22+
| Enforce coding style and formatting rules? | [references/editorconfig.md](references/editorconfig.md) |
23+
24+
---
25+
26+
## Modern defaults to always apply
27+
28+
These are the baseline quality settings for every new .NET 10 solution. Do not
29+
omit them — they represent the minimum for professional .NET development today.
30+
31+
**In `Directory.Build.props`:**
32+
```xml
33+
<TargetFramework>net10.0</TargetFramework>
34+
<LangVersion>latest</LangVersion>
35+
<Nullable>enable</Nullable>
36+
<ImplicitUsings>enable</ImplicitUsings>
37+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
38+
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
39+
<EnableNETAnalyzers>true</EnableNETAnalyzers>
40+
<AnalysisLevel>latest</AnalysisLevel>
41+
```
42+
43+
Every setting has a reason:
44+
- `LangVersion=latest` — gets C# 13/14 features without waiting for SDK bumps
45+
- `Nullable=enable` — null safety enforced at compile time
46+
- `TreatWarningsAsErrors=true` — stops warnings being silently ignored
47+
- `EnforceCodeStyleInBuild=true``.editorconfig` style rules fail the build
48+
- `AnalysisLevel=latest` — enables the newest Roslyn analyzer rules
49+
50+
**Use `.slnx`** for any new solution (it's the .NET 10 default). See
51+
[references/solution.md](references/solution.md) for details and migration.
52+
53+
**Enable Central Package Management** for any multi-project solution. See
54+
[references/packages-props.md](references/packages-props.md).
55+
56+
---
57+
58+
## Common project skeleton
59+
60+
```
61+
repo/
62+
├── .editorconfig ← code style rules (root = true)
63+
├── .gitignore ← standard .NET gitignore
64+
├── global.json ← pin the SDK version
65+
├── Directory.Build.props ← shared MSBuild properties (early)
66+
├── Directory.Build.targets ← shared MSBuild targets (late)
67+
├── Directory.Packages.props ← central NuGet versions
68+
├── MySolution.slnx ← solution file (.NET 10 default format)
69+
├── src/
70+
│ ├── MyApp.Api/
71+
│ │ └── MyApp.Api.csproj
72+
│ └── MyApp.Core/
73+
│ └── MyApp.Core.csproj
74+
└── tests/
75+
└── MyApp.Tests/
76+
└── MyApp.Tests.csproj
77+
```
78+
79+
---
80+
81+
## Rules
82+
83+
```
84+
✅ .slnx ❌ .sln (for new solutions)
85+
✅ Directory.Build.props ❌ Repeating <TargetFramework> in every .csproj
86+
✅ Directory.Packages.props ❌ Version attributes on <PackageReference>
87+
✅ <LangVersion>latest</LangVersion> ❌ Pinning to a specific version number
88+
✅ <Nullable>enable</Nullable> ❌ Missing or disabled nullable
89+
✅ file-scoped namespaces ❌ braced namespace blocks
90+
```
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Directory.Build.props and Directory.Build.targets
2+
3+
## What they are
4+
5+
`Directory.Build.props` and `Directory.Build.targets` are MSBuild files that
6+
are automatically imported into every project in the directory tree beneath them.
7+
The key difference is *when* they're imported:
8+
9+
| File | Import point | Use for |
10+
|------|-------------|---------|
11+
| `Directory.Build.props` | Early (before SDK defaults) | Properties that configure the SDK |
12+
| `Directory.Build.targets` | Late (after NuGet targets) | Custom build targets, post-build actions |
13+
14+
Placing them at the repository root means all projects share the same settings
15+
automatically — no property repetition in individual `.csproj` files.
16+
17+
Create them quickly via the CLI:
18+
```bash
19+
dotnet new buildprops # creates Directory.Build.props
20+
```
21+
22+
---
23+
24+
## Recommended Directory.Build.props for .NET 10
25+
26+
```xml
27+
<Project>
28+
<PropertyGroup>
29+
<!-- Framework & Language -->
30+
<TargetFramework>net10.0</TargetFramework>
31+
<LangVersion>latest</LangVersion>
32+
<Nullable>enable</Nullable>
33+
<ImplicitUsings>enable</ImplicitUsings>
34+
35+
<!-- Code quality — all three enforce style/analysis at build time -->
36+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
37+
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
38+
<EnableNETAnalyzers>true</EnableNETAnalyzers>
39+
<AnalysisLevel>latest</AnalysisLevel>
40+
41+
<!-- Source generation — exposes generated files in obj/ for debugging -->
42+
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
43+
44+
<!-- Package metadata (for libraries) -->
45+
<Authors>Your Name</Authors>
46+
<Copyright>Copyright (c) 2025 Your Name</Copyright>
47+
</PropertyGroup>
48+
49+
<!-- Deterministic + SourceLink for reproducible builds -->
50+
<PropertyGroup>
51+
<Deterministic>true</Deterministic>
52+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
53+
<EmbedUntrackedSources>true</EmbedUntrackedSources>
54+
<IncludeSymbols>true</IncludeSymbols>
55+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
56+
</PropertyGroup>
57+
58+
<!-- CI-only: reproducible builds on GitHub Actions -->
59+
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
60+
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
61+
</PropertyGroup>
62+
63+
<!-- Shared analyzer packages — applied to every project automatically -->
64+
<ItemGroup>
65+
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="all" />
66+
</ItemGroup>
67+
</Project>
68+
```
69+
70+
---
71+
72+
## Property explanations
73+
74+
**`LangVersion=latest`** — automatically uses the latest C# version supported by
75+
the installed SDK (C# 13 in .NET 9, C# 14 in .NET 10). Never pin to a specific
76+
number; you'll miss new features unnecessarily.
77+
78+
**`Nullable=enable`** — enables nullable reference types. This is one of the
79+
highest-value safety features in modern C#. With it enabled you'll get compile-
80+
time warnings for potential null dereferences.
81+
82+
**`TreatWarningsAsErrors=true`** — turns all warnings into errors. Without this,
83+
warnings accumulate silently and never get fixed. Pair it with `<NoWarn>` for
84+
intentional suppression of specific warnings:
85+
```xml
86+
<NoWarn>$(NoWarn);CS1591</NoWarn> <!-- suppress missing XML docs -->
87+
```
88+
89+
**`EnforceCodeStyleInBuild=true`** — causes `.editorconfig` style rules to
90+
produce build errors/warnings rather than just IDE squiggles. This makes code
91+
style enforceable in CI.
92+
93+
**`AnalysisLevel=latest`** — enables the newest generation of Roslyn code
94+
quality rules as soon as they're available in the SDK.
95+
96+
**`EmitCompilerGeneratedFiles=true`** — writes source-generated files (e.g.,
97+
from `System.Text.Json`, `RegexGenerator`, `LoggerMessage`) into `obj/` so you
98+
can inspect them. Harmless and very helpful for debugging generators.
99+
100+
---
101+
102+
## Directory.Build.targets
103+
104+
Use `.targets` for things that must run *after* the project and NuGet imports,
105+
or that define build targets:
106+
107+
```xml
108+
<Project>
109+
<!-- Enforce code analysis across all projects -->
110+
<PropertyGroup>
111+
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
112+
</PropertyGroup>
113+
114+
<!-- Custom post-build target — e.g., log output path -->
115+
<Target Name="LogBuildOutput" AfterTargets="Build">
116+
<Message Importance="high" Text="Built $(MSBuildProjectName) → $(TargetPath)" />
117+
</Target>
118+
</Project>
119+
```
120+
121+
---
122+
123+
## Multi-level merging
124+
125+
By default MSBuild stops scanning upward after finding the first
126+
`Directory.Build.props`. To support per-folder overrides that also inherit
127+
from the root file, add this to the inner file:
128+
129+
```xml
130+
<!-- tests/Directory.Build.props -->
131+
<Project>
132+
<!-- Import the root settings first -->
133+
<Import Project="$([MSBuild]::GetPathOfFileAbove(
134+
'Directory.Build.props',
135+
'$(MSBuildThisFileDirectory)../'))"
136+
Condition="'' != $([MSBuild]::GetPathOfFileAbove(
137+
'Directory.Build.props',
138+
'$(MSBuildThisFileDirectory)../'))" />
139+
140+
<!-- Test-only overrides -->
141+
<PropertyGroup>
142+
<IsTestProject>true</IsTestProject>
143+
</PropertyGroup>
144+
</Project>
145+
```
146+
147+
This is useful for applying different settings to `src/` vs `tests/`.
148+
149+
---
150+
151+
## Overriding in individual projects
152+
153+
Settings from `Directory.Build.props` are defaults. Any project can override
154+
them by setting the property in its own `.csproj`:
155+
156+
```xml
157+
<Project Sdk="Microsoft.NET.Sdk">
158+
<PropertyGroup>
159+
<!-- This project targets multiple frameworks -->
160+
<TargetFrameworks>net10.0;netstandard2.0</TargetFrameworks>
161+
162+
<!-- Disable TreatWarningsAsErrors for generated code projects -->
163+
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
164+
</PropertyGroup>
165+
</Project>
166+
```
167+
168+
---
169+
170+
## Troubleshooting
171+
172+
**Property not taking effect**: Run `dotnet msbuild /pp:preprocessed.xml MyProj.csproj`
173+
to see the full merged file with import order. Look for where your property is set
174+
vs where it's overridden.
175+
176+
**File silently ignored on Linux/macOS**: The filename must match exactly —
177+
`Directory.Build.props` (capital B and capital P). Linux filesystems are
178+
case-sensitive.
179+
180+
**Visual Studio not picking up changes**: Close and reopen the solution, or
181+
right-click → Reload Project after editing `.props` or `.targets` files.

0 commit comments

Comments
 (0)