CNinnovation.Templates.SourceGenerator
2.1.0
Prefix Reserved
dotnet new install CNinnovation.Templates.SourceGenerator::2.1.0
MyGenerator — .NET Source Generator Template
This template scaffolds a complete .NET source generator solution that includes:
MyGenerator/– The source generator project (netstandard2.0)MyGenerator.Tests/– Unit tests using xUnit v3MyGenerator.SnapshotTests/– Snapshot tests using xUnit v3 + Verify
Using the Template
Install the template from NuGet:
dotnet new install CNinnovation.Templates.SourceGenerator
Scaffold a new generator solution:
dotnet new cni-sourcegen -n AwesomeGenerator
cd AwesomeGenerator
Remove the template installation when no longer needed:
dotnet new uninstall CNinnovation.Templates.SourceGenerator
Project Structure
AwesomeGenerator/
├── AwesomeGenerator/ # Source generator (netstandard2.0 by default)
│ ├── AwesomeGenerator.csproj
│ └── AwesomeGeneratorImpl.cs # IIncrementalGenerator implementation
│
├── AwesomeGenerator.Tests/ # xUnit v3 unit tests
│ ├── AwesomeGenerator.Tests.csproj
│ ├── GlobalUsings.cs
│ ├── TestHelper.cs # Compiles code and runs the generator
│ └── AwesomeGeneratorTests.cs
│
├── AwesomeGenerator.SnapshotTests/ # xUnit v3 snapshot tests via Verify
│ ├── AwesomeGenerator.SnapshotTests.csproj
│ ├── GlobalUsings.cs
│ ├── TestHelper.cs # Runs generator and calls Verifier.Verify
│ ├── AwesomeGeneratorSnapshotTests.cs
│ └── Snapshots/ # Verified snapshot files live here
│
└── AwesomeGenerator.slnx # Solution file
Getting Started
Build
dotnet build AwesomeGenerator.slnx
Run Unit Tests
dotnet test AwesomeGenerator.Tests/AwesomeGenerator.Tests.csproj
Run Snapshot Tests
dotnet test AwesomeGenerator.SnapshotTests/AwesomeGenerator.SnapshotTests.csproj
Run All Tests
dotnet test AwesomeGenerator.slnx
How the Generator Works
The template implements a simple but realistic pattern:
Inject an attribute –
GenerateInfoAttributeis added to every compilation viaRegisterPostInitializationOutput.Detect marked classes – one of two approaches is used (selected at scaffold time):
CreateSyntaxProvider(default) – visits all class declarations, uses a fast syntactic predicate to filter candidates, then a semantic transform to confirm the attribute is present. Flexible and general-purpose.ForAttributeWithMetadataName– tells Roslyn to watch specifically for[GenerateInfo]by its fully-qualified metadata name. Roslyn only invokes the transform for nodes that already carry the attribute, making it more efficient for attribute-driven generators. Recommended when a single well-known attribute triggers generation.
Generate a companion class – For each marked class a
<ClassName>Infostatic class is generated containing compile-time constants (type name, property count, method count) and aGetSummary()method.
Replace GenerateInfoAttribute and the corresponding generation logic in
MyGeneratorImpl.cs with your own attribute and code generation.
Choosing a Syntax Provider Mode
| Option | Flag | Best for |
|---|---|---|
CreateSyntaxProvider |
(default) | Any syntax-based detection; maximum flexibility |
ForAttributeWithMetadataName |
-m ForAttributeWithMetadataName |
Attribute-driven generators; better incremental performance |
# scaffold with the optimized attribute-based approach
dotnet new cni-sourcegen -n AwesomeGenerator -m ForAttributeWithMetadataName
Snapshot Testing with Verify
Snapshot tests use the Verify library together
with Verify.SourceGenerators to capture and compare the exact text of every generated
source file.
Running the Bundled Snapshot Tests
The template ships with two pre-accepted .verified.txt files in MyGenerator.SnapshotTests/Snapshots/, so the included snapshot tests pass immediately without any extra setup.
First Run for New Tests
When you add a new snapshot test (or modify the generator), no .verified.txt file exists yet for that test. Verify will:
- Write a
.received.txtfile inSnapshots/next to the test class. - Fail the test so you can inspect the output.
- Accept it once the output looks correct (see below).
Accepting / Updating Snapshots
Via environment variable (useful in CI pipelines):
VERIFY_AUTO_APPROVE=true dotnet test AwesomeGenerator.SnapshotTests
Via test runner argument:
dotnet test AwesomeGenerator.SnapshotTests -- Verify.AutoVerify=true
Manually: Rename the .received.txt file to .verified.txt (remove the received
segment) and commit it.
Snapshot File Location
Verified snapshots are stored in MyGenerator.SnapshotTests/Snapshots/ and should be
committed to source control so that future test runs can detect regressions.
xUnit v3
This template targets xUnit v3 (xunit.v3 NuGet package), which provides:
- Improved parallelism and performance
- Cleaner async test support
- Better extensibility model
All standard xUnit attributes ([Fact], [Theory], [InlineData], etc.) work the
same as in xUnit v2.
Customizing the Generator
- Open
MyGeneratorImpl.csand replace theGenerateInfoattribute name and logic with your own. - Update
MyGeneratorTests.csandMyGeneratorSnapshotTests.cswith tests for your new behavior. - Run
dotnet testto verify everything works. - Accept new snapshots as described above.
Requirements
- .NET SDK matching the selected test TFM (for example,
net9.0ornet10.0) - C# 13 (LangVersion
latestis set automatically)
Third-Party Dependencies
This template uses the following NuGet packages:
Source Generator
- Microsoft.CodeAnalysis.CSharp (5.0.0) – Roslyn C# compiler API
- Microsoft.CodeAnalysis.Analyzers (4.14.0) – Analyzer development tools
Test Projects
- xUnit v3 (3.2.2) – Unit testing framework
- Microsoft.NET.Test.Sdk (18.3.0) – Test platform
- xunit.runner.visualstudio (3.1.5) – Visual Studio test runner
- coverlet.collector (8.0.0) – Code coverage collector
Snapshot Testing
- Verify.XunitV3 (31.13.2) – Snapshot testing library
- Verify.SourceGenerators (2.5.0) – Source generator snapshot extensions
For complete license information and attribution, see THIRD-PARTY-NOTICES.md.
All dependencies use permissive open-source licenses (MIT or Apache-2.0).
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.