williamzujkowski

C# .NET Tooling Specialist

3
0
# Install this skill:
npx skills add williamzujkowski/cognitive-toolworks --skill "C# .NET Tooling Specialist"

Install specific skill from multi-skill repository

# Description

Generate C# .NET project scaffolding with dotnet CLI, xUnit/NUnit, StyleCop analyzers, and packaging (NuGet/Docker).

# SKILL.md


name: "C# .NET Tooling Specialist"
slug: "tooling-csharp-generator"
description: "Generate C# .NET project scaffolding with dotnet CLI, xUnit/NUnit, StyleCop analyzers, and packaging (NuGet/Docker)."
capabilities:
- Project structure generation (library, console, web-api, blazor, wpf, maui)
- Build tool setup (dotnet CLI, MSBuild, solution files)
- Testing framework configuration (xUnit, NUnit, MSTest, Moq)
- Code quality tools (StyleCop, Roslyn analyzers, SonarAnalyzer)
- Packaging and distribution (NuGet, Docker, native AOT)
- ASP.NET Core setup (minimal APIs, MVC, Blazor)
inputs:
- project_type: "library | console | web-api | blazor | wpf | maui (string)"
- dotnet_version: "6.0 | 7.0 | 8.0 (string)"
- test_framework: "xunit | nunit | mstest (string)"
- project_name: "Name of the project (string)"
outputs:
- project_structure: "Directory layout with all config files (JSON)"
- csproj_file: "Complete .csproj configuration"
- solution_file: ".sln file for multi-project solutions"
- test_project: "Test project configuration"
keywords:
- csharp
- dotnet
- tooling
- nuget
- xunit
- aspnet
- blazor
- roslyn
- msbuild
version: "1.0.0"
owner: "cognitive-toolworks"
license: "MIT"
security: "Public; no secrets or PII; safe for open repositories"
links:
- https://learn.microsoft.com/en-us/dotnet/core/
- https://learn.microsoft.com/en-us/aspnet/core/
- https://xunit.net/docs/getting-started/netcore/
- https://learn.microsoft.com/en-us/nuget/
- https://github.com/DotNetAnalyzers/StyleCopAnalyzers


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:
- .NET docs must be accessible accessed 2025-10-26
- ASP.NET Core docs must be accessible accessed 2025-10-26
- xUnit docs must be accessible accessed 2025-10-26
- NuGet docs must be accessible accessed 2025-10-26


Procedure

T1: Basic Project Structure (≤2k tokens)

Fast path for common cases:

  1. Directory Layout Generation
    ProjectName/ src/ ProjectName/ ProjectName.csproj Class1.cs tests/ ProjectName.Tests/ ProjectName.Tests.csproj UnitTest1.cs ProjectName.sln .gitignore README.md

  2. Core .csproj accessed 2025-10-26
    ```xml


    net8.0
    enable
    enable
    latest



    all
    runtime; build; native; contentfiles; analyzers



    ```

  3. 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:

  1. Testing Framework Configuration

xUnit accessed 2025-10-26
```xml


net8.0
false
true

 <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>


```

NUnit (alternative) accessed 2025-10-26
xml <ItemGroup> <PackageReference Include="NUnit" Version="4.1.0" /> <PackageReference Include="NUnit3TestAdapter" Version="4.5.0" /> <PackageReference Include="NUnit.Analyzers" Version="4.1.0" /> </ItemGroup>

  1. Code Quality and Analyzers

StyleCop + Roslyn Analyzers accessed 2025-10-26
xml <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:
```ini
# 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
```

  1. ASP.NET Core Web API

Minimal API accessed 2025-10-26
```xml


net8.0
enable
enable

 <ItemGroup>
   <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" />
   <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
 </ItemGroup>


```

Program.cs (minimal API):
```csharp
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();
```

  1. Blazor WebAssembly

```xml


net8.0

 <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>


```


T3: Advanced Configuration (≤12k tokens)

Deep configuration for NuGet packaging and production:

  1. NuGet Package Configuration accessed 2025-10-26

```xml


net8.0
true
CompanyName.ProjectName
1.0.0
Your Name
Company Name
Package description
tag1;tag2;tag3
MIT
https://github.com/user/repo
https://github.com/user/repo
git
true
true
true
snupkg

 <ItemGroup>
   <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
 </ItemGroup>


```

  1. Multi-Target Framework

```xml

net6.0;net7.0;net8.0






```

  1. Native AOT Publishing accessed 2025-10-26

xml <PropertyGroup> <PublishAot>true</PublishAot> <InvariantGlobalization>true</InvariantGlobalization> <JsonSerializerIsReflectionEnabledByDefault>false</JsonSerializerIsReflectionEnabledByDefault> </PropertyGroup>

Publish command:
bash dotnet publish -c Release -r linux-x64 --self-contained

  1. Docker Configuration

Dockerfile (multi-stage):
```dockerfile
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

  1. CI/CD Pipeline (GitHub Actions)

```.github/workflows/dotnet.yml
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
```

  1. Solution-Level Configuration

Directory.Build.props (applies to all projects):
xml <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):
1. .NET Documentation - Core .NET reference
2. ASP.NET Core Documentation - Web framework
3. xUnit Getting Started - Testing framework
4. NuGet Documentation - Package management
5. StyleCop Analyzers - Code quality
6. Blazor Documentation - WebAssembly/Server
7. .NET MAUI Documentation - Cross-platform apps

Testing:
- NUnit - Alternative testing framework
- MSTest - Microsoft testing framework
- Moq - Mocking library
- FluentAssertions - Assertion library

Build Tools:
- MSBuild - Build engine
- Native AOT - Ahead-of-time compilation

Best Practices:
- C# Coding Conventions - Style guide
- .NET Design Guidelines - API design

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.