Purpose & When-To-Use
Trigger conditions:
- Starting a new C# .NET project requiring modern tooling
- Creating ASP.NET Core web APIs or Blazor applications
- Building cross-platform console applications or libraries
- Setting up .NET MAUI mobile applications
- Creating NuGet packages for distribution
- Migrating .NET Framework projects to .NET Core/5+
Not for:
- Legacy .NET Framework 4.x projects (use older MSBuild templates)
- Unity game development (use Unity's project templates)
- Xamarin projects (migrated to .NET MAUI)
Pre-Checks
Time normalization:
- Compute
NOW_ET using NIST/time.gov semantics (America/New_York, ISO-8601)
- Use
NOW_ET for all citation access dates
Input validation:
project_type must be one of: library, console, web-api, blazor, wpf, maui
dotnet_version must be one of: 6.0, 7.0, 8.0
test_framework must be one of: xunit, nunit, mstest
project_name must be valid .NET identifier (PascalCase recommended)
Source freshness:
Procedure
T1: Basic Project Structure (≤2k tokens)
Fast path for common cases:
Directory Layout Generation
ProjectName/
src/
ProjectName/
ProjectName.csproj
Class1.cs
tests/
ProjectName.Tests/
ProjectName.Tests.csproj
UnitTest1.cs
ProjectName.sln
.gitignore
README.md
Core .csproj accessed 2025-10-26
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
Solution File (.sln)
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectName", "src\ProjectName\ProjectName.csproj", "{GUID}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectName.Tests", "tests\ProjectName.Tests\ProjectName.Tests.csproj", "{GUID}"
EndProject
Decision: If only basic scaffolding needed → STOP at T1; otherwise proceed to T2.
T2: Full Tooling Setup (≤6k tokens)
Extended configuration with testing and web frameworks:
Testing Framework Configuration
xUnit accessed 2025-10-26
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="xunit" Version="2.7.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\ProjectName\ProjectName.csproj" />
</ItemGroup>
</Project>
NUnit (alternative) accessed 2025-10-26
<ItemGroup>
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.1.0" />
</ItemGroup>
Code Quality and Analyzers
StyleCop + Roslyn Analyzers accessed 2025-10-26
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.23.0.88079">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
.editorconfig:
# Top-most EditorConfig file
root = true
[*.cs]
# Code style rules
dotnet_sort_system_directives_first = true
csharp_style_var_for_built_in_types = true
csharp_style_var_when_type_is_apparent = true
# Naming conventions
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.severity = warning
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.symbols = interface
dotnet_naming_rule.interfaces_should_be_prefixed_with_i.style = begins_with_i
# StyleCop rules
dotnet_diagnostic.SA1633.severity = none # File header
dotnet_diagnostic.SA1200.severity = none # Using directives placement
ASP.NET Core Web API
Minimal API accessed 2025-10-26
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
</Project>
Program.cs (minimal API):
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapGet("/api/health", () => Results.Ok(new { status = "healthy" }))
.WithName("GetHealth")
.WithOpenApi();
app.Run();
Blazor WebAssembly
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.4" PrivateAssets="all" />
</ItemGroup>
</Project>
T3: Advanced Configuration (≤12k tokens)
Deep configuration for NuGet packaging and production:
NuGet Package Configuration accessed 2025-10-26
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>CompanyName.ProjectName</PackageId>
<Version>1.0.0</Version>
<Authors>Your Name</Authors>
<Company>Company Name</Company>
<Description>Package description</Description>
<PackageTags>tag1;tag2;tag3</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/user/repo</PackageProjectUrl>
<RepositoryUrl>https://github.com/user/repo</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
</ItemGroup>
</Project>
Multi-Target Framework
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="System.Text.Json" Version="6.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="System.Text.Json" Version="8.0.0" />
</ItemGroup>
Native AOT Publishing accessed 2025-10-26
<PropertyGroup>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
<JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>
</PropertyGroup>
Publish command:
dotnet publish -c Release -r linux-x64 --self-contained
Docker Configuration
Dockerfile (multi-stage):
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["src/ProjectName/ProjectName.csproj", "src/ProjectName/"]
RUN dotnet restore "src/ProjectName/ProjectName.csproj"
COPY . .
WORKDIR "/src/src/ProjectName"
RUN dotnet build "ProjectName.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ProjectName.csproj" -c Release -o /app/publish
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app
EXPOSE 8080
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProjectName.dll"]
.dockerignore:
**/bin
**/obj
**/out
**/.vs
**/.vscode
CI/CD Pipeline (GitHub Actions)
name: .NET CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal --collect:"XPlat Code Coverage"
- name: Upload coverage
uses: codecov/codecov-action@v4
Solution-Level Configuration
Directory.Build.props (applies to all projects):
<Project>
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
</PropertyGroup>
</Project>
Decision Rules
Project Type Selection:
- library: Class library for NuGet distribution, multi-targeting
- console: Command-line application, single executable
- web-api: ASP.NET Core minimal API or MVC for REST services
- blazor: Blazor WebAssembly or Server for SPAs
- wpf: Windows desktop application (Windows-only)
- maui: Cross-platform mobile and desktop (.NET MAUI)
Test Framework Selection:
- xUnit: Modern, recommended for new projects, parallel execution
- NUnit: Mature, feature-rich, parameterized tests
- MSTest: Microsoft's framework, Visual Studio integration
Abort Conditions:
- Invalid
project_name (contains spaces, special chars) → error
- Conflicting frameworks (WPF + MAUI) → error
- Unsupported .NET version → error
.NET Version Selection:
- Use .NET 8.0 for new projects (LTS with long-term support)
- .NET 6.0 for compatibility with older systems (LTS)
- .NET 7.0 for latest features (standard support)
Output Contract
Schema (JSON):
{
"project_name": "string",
"project_type": "library | console | web-api | blazor | wpf | maui",
"dotnet_version": "string",
"test_framework": "xunit | nunit | mstest",
"structure": {
"directories": ["string"],
"files": {
"path/to/file": "file content (string)"
}
},
"commands": {
"restore": "string",
"build": "string",
"test": "string",
"run": "string",
"publish": "string"
},
"next_steps": ["string"],
"timestamp": "ISO-8601 string (NOW_ET)"
}
Required Fields:
- All fields mandatory
- File contents must be syntactically valid (XML, C#, JSON)
- Include inline comments explaining configuration choices
Examples
Quick Start: C# Library (26 lines)
// examples/LibraryExample.cs
namespace Example.Utils;
public sealed class TextAnalyzer
{
public record AnalysisResult(int Length, int WordCount, DateTime Analyzed);
private readonly List<string> _history = new();
public AnalysisResult Analyze(string text)
{
ArgumentException.ThrowIfNullOrWhiteSpace(text);
_history.Add(text);
var wordCount = text.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length;
return new AnalysisResult(text.Length, wordCount, DateTime.UtcNow);
}
public IReadOnlyList<string> GetHistory() => _history.AsReadOnly();
public void Clear() => _history.Clear();
}
Additional Examples:
- CLI Tool:
examples/CliExample.cs (22 lines) - System.CommandLine, async/await, file I/O
- Minimal API:
examples/ApiExample.cs (30 lines) - ASP.NET Core endpoints, concurrent collections
Template Resources (see resources/)
- .csproj:
Library.csproj / Console.csproj / WebApi.csproj
- Testing:
Tests.csproj with xUnit, Moq, FluentAssertions / ExampleTest.cs
- Packaging:
NuGetPackage.csproj - complete NuGet metadata and SourceLink
Quality Gates
Token Budgets:
- T1: ≤2k tokens (basic structure + .csproj + .sln)
- T2: ≤6k tokens (testing, analyzers, ASP.NET Core, Blazor)
- T3: ≤12k tokens (NuGet packaging, multi-targeting, Docker, CI/CD, native AOT)
Safety:
- No hardcoded API keys or secrets
- .gitignore includes bin/, obj/, .vs/, .user files
- Roslyn analyzers configured to catch security issues
Auditability:
- All configurations cite official Microsoft documentation
- Version constraints explicit
- Generation timestamp included
Determinism:
- Same inputs → identical structure
- Versions pinned where appropriate
- No randomness in generation
Performance:
- T1 generation: <1 second
- T2 generation: <3 seconds
- T3 generation: <5 seconds
Resources
Official Documentation (accessed 2025-10-26):
- .NET Documentation - Core .NET reference
- ASP.NET Core Documentation - Web framework
- xUnit Getting Started - Testing framework
- NuGet Documentation - Package management
- StyleCop Analyzers - Code quality
- Blazor Documentation - WebAssembly/Server
- .NET MAUI Documentation - Cross-platform apps
Testing:
Build Tools:
Best Practices:
1---2name: c-net-tooling-specialist3description: Generate C# .NET project scaffolding with dotnet CLI, xUnit/NUnit, StyleCop analyzers, and packaging (NuGet/Docker).4license: MIT5---67## Purpose & When-To-Use89**Trigger conditions:**10- Starting a new C# .NET project requiring modern tooling11- Creating ASP.NET Core web APIs or Blazor applications12- Building cross-platform console applications or libraries13- Setting up .NET MAUI mobile applications14- Creating NuGet packages for distribution15- Migrating .NET Framework projects to .NET Core/5+1617**Not for:**18- Legacy .NET Framework 4.x projects (use older MSBuild templates)19- Unity game development (use Unity's project templates)20- Xamarin projects (migrated to .NET MAUI)2122---2324## Pre-Checks2526**Time normalization:**27- Compute `NOW_ET` using NIST/time.gov semantics (America/New_York, ISO-8601)28- Use `NOW_ET` for all citation access dates2930**Input validation:**31- `project_type` must be one of: library, console, web-api, blazor, wpf, maui32- `dotnet_version` must be one of: 6.0, 7.0, 8.033- `test_framework` must be one of: xunit, nunit, mstest34- `project_name` must be valid .NET identifier (PascalCase recommended)3536**Source freshness:**37- .NET docs must be accessible [accessed 2025-10-26](https://learn.microsoft.com/en-us/dotnet/core/)38- ASP.NET Core docs must be accessible [accessed 2025-10-26](https://learn.microsoft.com/en-us/aspnet/core/)39- xUnit docs must be accessible [accessed 2025-10-26](https://xunit.net/docs/getting-started/netcore/)40- NuGet docs must be accessible [accessed 2025-10-26](https://learn.microsoft.com/en-us/nuget/)4142---4344## Procedure4546### T1: Basic Project Structure (≤2k tokens)4748**Fast path for common cases:**49501. **Directory Layout Generation**51 ```52 ProjectName/53 src/54 ProjectName/55 ProjectName.csproj56 Class1.cs57 tests/58 ProjectName.Tests/59 ProjectName.Tests.csproj60 UnitTest1.cs61 ProjectName.sln62 .gitignore63 README.md64 ```65662. **Core .csproj** [accessed 2025-10-26](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview)67 ```xml68 <Project Sdk="Microsoft.NET.Sdk">69 <PropertyGroup>70 <TargetFramework>net8.0</TargetFramework>71 <Nullable>enable</Nullable>72 <ImplicitUsings>enable</ImplicitUsings>73 <LangVersion>latest</LangVersion>74 </PropertyGroup>7576 <ItemGroup>77 <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">78 <PrivateAssets>all</PrivateAssets>79 <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>80 </PackageReference>81 </ItemGroup>82 </Project>83 ```84853. **Solution File** (.sln)86 ```87 Microsoft Visual Studio Solution File, Format Version 12.0088 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectName", "src\ProjectName\ProjectName.csproj", "{GUID}"89 EndProject90 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectName.Tests", "tests\ProjectName.Tests\ProjectName.Tests.csproj", "{GUID}"91 EndProject92 ```9394**Decision:** If only basic scaffolding needed → STOP at T1; otherwise proceed to T2.9596---9798### T2: Full Tooling Setup (≤6k tokens)99100**Extended configuration with testing and web frameworks:**1011021. **Testing Framework Configuration**103104 **xUnit** [accessed 2025-10-26](https://xunit.net/docs/getting-started/netcore/)105 ```xml106 <Project Sdk="Microsoft.NET.Sdk">107 <PropertyGroup>108 <TargetFramework>net8.0</TargetFramework>109 <IsPackable>false</IsPackable>110 <IsTestProject>true</IsTestProject>111 </PropertyGroup>112113 <ItemGroup>114 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />115 <PackageReference Include="xunit" Version="2.7.0" />116 <PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">117 <PrivateAssets>all</PrivateAssets>118 <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>119 </PackageReference>120 <PackageReference Include="Moq" Version="4.20.70" />121 <PackageReference Include="FluentAssertions" Version="6.12.0" />122 <PackageReference Include="coverlet.collector" Version="6.0.0">123 <PrivateAssets>all</PrivateAssets>124 <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>125 </PackageReference>126 </ItemGroup>127128 <ItemGroup>129 <ProjectReference Include="..\..\src\ProjectName\ProjectName.csproj" />130 </ItemGroup>131 </Project>132 ```133134 **NUnit** (alternative) [accessed 2025-10-26](https://docs.nunit.org/)135 ```xml136 <ItemGroup>137 <PackageReference Include="NUnit" Version="4.1.0" />138 <PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />139 <PackageReference Include="NUnit.Analyzers" Version="4.1.0" />140 </ItemGroup>141 ```1421432. **Code Quality and Analyzers**144145 **StyleCop + Roslyn Analyzers** [accessed 2025-10-26](https://github.com/DotNetAnalyzers/StyleCopAnalyzers)146 ```xml147 <ItemGroup>148 <PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556">149 <PrivateAssets>all</PrivateAssets>150 <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>151 </PackageReference>152 <PackageReference Include="SonarAnalyzer.CSharp" Version="9.23.0.88079">153 <PrivateAssets>all</PrivateAssets>154 <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>155 </PackageReference>156 </ItemGroup>157 ```158159 .editorconfig:160 ```ini161 # Top-most EditorConfig file162 root = true163164 [*.cs]165 # Code style rules166 dotnet_sort_system_directives_first = true167 csharp_style_var_for_built_in_types = true168 csharp_style_var_when_type_is_apparent = true169170 # Naming conventions171 dotnet_naming_rule.interfaces_should_be_prefixed_with_i.severity = warning172 dotnet_naming_rule.interfaces_should_be_prefixed_with_i.symbols = interface173 dotnet_naming_rule.interfaces_should_be_prefixed_with_i.style = begins_with_i174175 # StyleCop rules176 dotnet_diagnostic.SA1633.severity = none # File header177 dotnet_diagnostic.SA1200.severity = none # Using directives placement178 ```1791803. **ASP.NET Core Web API**181182 **Minimal API** [accessed 2025-10-26](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis)183 ```xml184 <Project Sdk="Microsoft.NET.Sdk.Web">185 <PropertyGroup>186 <TargetFramework>net8.0</TargetFramework>187 <Nullable>enable</Nullable>188 <ImplicitUsings>enable</ImplicitUsings>189 </PropertyGroup>190191 <ItemGroup>192 <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" />193 <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />194 </ItemGroup>195 </Project>196 ```197198 Program.cs (minimal API):199 ```csharp200 var builder = WebApplication.CreateBuilder(args);201202 builder.Services.AddEndpointsApiExplorer();203 builder.Services.AddSwaggerGen();204205 var app = builder.Build();206207 if (app.Environment.IsDevelopment())208 {209 app.UseSwagger();210 app.UseSwaggerUI();211 }212213 app.UseHttpsRedirection();214215 app.MapGet("/api/health", () => Results.Ok(new { status = "healthy" }))216 .WithName("GetHealth")217 .WithOpenApi();218219 app.Run();220 ```2212224. **Blazor WebAssembly**223224 ```xml225 <Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">226 <PropertyGroup>227 <TargetFramework>net8.0</TargetFramework>228 </PropertyGroup>229230 <ItemGroup>231 <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.4" />232 <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.4" PrivateAssets="all" />233 </ItemGroup>234 </Project>235 ```236237---238239### T3: Advanced Configuration (≤12k tokens)240241**Deep configuration for NuGet packaging and production:**2422431. **NuGet Package Configuration** [accessed 2025-10-26](https://learn.microsoft.com/en-us/nuget/create-packages/creating-a-package-msbuild)244245 ```xml246 <Project Sdk="Microsoft.NET.Sdk">247 <PropertyGroup>248 <TargetFramework>net8.0</TargetFramework>249 <GeneratePackageOnBuild>true</GeneratePackageOnBuild>250 <PackageId>CompanyName.ProjectName</PackageId>251 <Version>1.0.0</Version>252 <Authors>Your Name</Authors>253 <Company>Company Name</Company>254 <Description>Package description</Description>255 <PackageTags>tag1;tag2;tag3</PackageTags>256 <PackageLicenseExpression>MIT</PackageLicenseExpression>257 <PackageProjectUrl>https://github.com/user/repo</PackageProjectUrl>258 <RepositoryUrl>https://github.com/user/repo</RepositoryUrl>259 <RepositoryType>git</RepositoryType>260 <PublishRepositoryUrl>true</PublishRepositoryUrl>261 <EmbedUntrackedSources>true</EmbedUntrackedSources>262 <IncludeSymbols>true</IncludeSymbols>263 <SymbolPackageFormat>snupkg</SymbolPackageFormat>264 </PropertyGroup>265266 <ItemGroup>267 <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />268 </ItemGroup>269 </Project>270 ```2712722. **Multi-Target Framework**273274 ```xml275 <PropertyGroup>276 <TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>277 </PropertyGroup>278279 <ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">280 <PackageReference Include="System.Text.Json" Version="6.0.0" />281 </ItemGroup>282283 <ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">284 <PackageReference Include="System.Text.Json" Version="8.0.0" />285 </ItemGroup>286 ```2872883. **Native AOT Publishing** [accessed 2025-10-26](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/)289290 ```xml291 <PropertyGroup>292 <PublishAot>true</PublishAot>293 <InvariantGlobalization>true</InvariantGlobalization>294 <JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault>295 </PropertyGroup>296 ```297298 Publish command:299 ```bash300 dotnet publish -c Release -r linux-x64 --self-contained301 ```3023034. **Docker Configuration**304305 Dockerfile (multi-stage):306 ```dockerfile307 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build308 WORKDIR /src309 COPY ["src/ProjectName/ProjectName.csproj", "src/ProjectName/"]310 RUN dotnet restore "src/ProjectName/ProjectName.csproj"311 COPY . .312 WORKDIR "/src/src/ProjectName"313 RUN dotnet build "ProjectName.csproj" -c Release -o /app/build314315 FROM build AS publish316 RUN dotnet publish "ProjectName.csproj" -c Release -o /app/publish317318 FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final319 WORKDIR /app320 EXPOSE 8080321 COPY --from=publish /app/publish .322 ENTRYPOINT ["dotnet", "ProjectName.dll"]323 ```324325 .dockerignore:326 ```327 **/bin328 **/obj329 **/out330 **/.vs331 **/.vscode332 ```3333345. **CI/CD Pipeline** (GitHub Actions)335336 ```.github/workflows/dotnet.yml337 name: .NET CI338339 on:340 push:341 branches: [ main ]342 pull_request:343 branches: [ main ]344345 jobs:346 build:347 runs-on: ubuntu-latest348 steps:349 - uses: actions/checkout@v4350 - name: Setup .NET351 uses: actions/setup-dotnet@v4352 with:353 dotnet-version: 8.0.x354 - name: Restore dependencies355 run: dotnet restore356 - name: Build357 run: dotnet build --no-restore358 - name: Test359 run: dotnet test --no-build --verbosity normal --collect:"XPlat Code Coverage"360 - name: Upload coverage361 uses: codecov/codecov-action@v4362 ```3633646. **Solution-Level Configuration**365366 Directory.Build.props (applies to all projects):367 ```xml368 <Project>369 <PropertyGroup>370 <TreatWarningsAsErrors>true</TreatWarningsAsErrors>371 <AnalysisMode>AllEnabledByDefault</AnalysisMode>372 <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>373 <EnableNETAnalyzers>true</EnableNETAnalyzers>374 </PropertyGroup>375 </Project>376 ```377378---379380## Decision Rules381382**Project Type Selection:**383- **library:** Class library for NuGet distribution, multi-targeting384- **console:** Command-line application, single executable385- **web-api:** ASP.NET Core minimal API or MVC for REST services386- **blazor:** Blazor WebAssembly or Server for SPAs387- **wpf:** Windows desktop application (Windows-only)388- **maui:** Cross-platform mobile and desktop (.NET MAUI)389390**Test Framework Selection:**391- **xUnit:** Modern, recommended for new projects, parallel execution392- **NUnit:** Mature, feature-rich, parameterized tests393- **MSTest:** Microsoft's framework, Visual Studio integration394395**Abort Conditions:**396- Invalid `project_name` (contains spaces, special chars) → error397- Conflicting frameworks (WPF + MAUI) → error398- Unsupported .NET version → error399400**.NET Version Selection:**401- Use .NET 8.0 for new projects (LTS with long-term support)402- .NET 6.0 for compatibility with older systems (LTS)403- .NET 7.0 for latest features (standard support)404405---406407## Output Contract408409**Schema (JSON):**410411```json412{413 "project_name": "string",414 "project_type": "library | console | web-api | blazor | wpf | maui",415 "dotnet_version": "string",416 "test_framework": "xunit | nunit | mstest",417 "structure": {418 "directories": ["string"],419 "files": {420 "path/to/file": "file content (string)"421 }422 },423 "commands": {424 "restore": "string",425 "build": "string",426 "test": "string",427 "run": "string",428 "publish": "string"429 },430 "next_steps": ["string"],431 "timestamp": "ISO-8601 string (NOW_ET)"432}433```434435**Required Fields:**436- All fields mandatory437- File contents must be syntactically valid (XML, C#, JSON)438- Include inline comments explaining configuration choices439440---441442## Examples443444**Quick Start: C# Library** (26 lines)445446```csharp447// examples/LibraryExample.cs448namespace Example.Utils;449450public sealed class TextAnalyzer451{452 public record AnalysisResult(int Length, int WordCount, DateTime Analyzed);453454 private readonly List<string> _history = new();455456 public AnalysisResult Analyze(string text)457 {458 ArgumentException.ThrowIfNullOrWhiteSpace(text);459 _history.Add(text);460 var wordCount = text.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length;461 return new AnalysisResult(text.Length, wordCount, DateTime.UtcNow);462 }463464 public IReadOnlyList<string> GetHistory() => _history.AsReadOnly();465466 public void Clear() => _history.Clear();467}468```469470**Additional Examples:**471- **CLI Tool**: `examples/CliExample.cs` (22 lines) - System.CommandLine, async/await, file I/O472- **Minimal API**: `examples/ApiExample.cs` (30 lines) - ASP.NET Core endpoints, concurrent collections473474**Template Resources** (see `resources/`)475- .csproj: `Library.csproj` / `Console.csproj` / `WebApi.csproj`476- Testing: `Tests.csproj` with xUnit, Moq, FluentAssertions / `ExampleTest.cs`477- Packaging: `NuGetPackage.csproj` - complete NuGet metadata and SourceLink478479---480481## Quality Gates482483**Token Budgets:**484- **T1:** ≤2k tokens (basic structure + .csproj + .sln)485- **T2:** ≤6k tokens (testing, analyzers, ASP.NET Core, Blazor)486- **T3:** ≤12k tokens (NuGet packaging, multi-targeting, Docker, CI/CD, native AOT)487488**Safety:**489- No hardcoded API keys or secrets490- .gitignore includes bin/, obj/, .vs/, .user files491- Roslyn analyzers configured to catch security issues492493**Auditability:**494- All configurations cite official Microsoft documentation495- Version constraints explicit496- Generation timestamp included497498**Determinism:**499- Same inputs → identical structure500- Versions pinned where appropriate501- No randomness in generation502503**Performance:**504- T1 generation: <1 second505- T2 generation: <3 seconds506- T3 generation: <5 seconds507508---509510## Resources511512**Official Documentation (accessed 2025-10-26):**5131. [.NET Documentation](https://learn.microsoft.com/en-us/dotnet/core/) - Core .NET reference5142. [ASP.NET Core Documentation](https://learn.microsoft.com/en-us/aspnet/core/) - Web framework5153. [xUnit Getting Started](https://xunit.net/docs/getting-started/netcore/) - Testing framework5164. [NuGet Documentation](https://learn.microsoft.com/en-us/nuget/) - Package management5175. [StyleCop Analyzers](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) - Code quality5186. [Blazor Documentation](https://learn.microsoft.com/en-us/aspnet/core/blazor/) - WebAssembly/Server5197. [.NET MAUI Documentation](https://learn.microsoft.com/en-us/dotnet/maui/) - Cross-platform apps520521**Testing:**522- [NUnit](https://docs.nunit.org/) - Alternative testing framework523- [MSTest](https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-with-mstest) - Microsoft testing framework524- [Moq](https://github.com/moq/moq4) - Mocking library525- [FluentAssertions](https://fluentassertions.com/) - Assertion library526527**Build Tools:**528- [MSBuild](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild) - Build engine529- [Native AOT](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/) - Ahead-of-time compilation530531**Best Practices:**532- [C# Coding Conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions) - Style guide533- [.NET Design Guidelines](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/) - API design