1---2name: dotnet3description: Router and complete index for .NET / C# specialist skills - maps a concrete work area (a construct, command, file, or task) to the one focused skill to load, across language & types, architecture & structure, ASP.NET Core & web, cross-cutting hardening, data & EF, messaging & orchestration, hosting & background work, testing & quality, diagnostics & performance, and desktop (WPF / WinForms). Routes per area, does not restate the skills. Load when starting or navigating any .NET / C# backend or desktop work - typed asks like 'add an endpoint to the orders API', 'my BackgroundService stopped overnight', or 'which skill covers EF Core queries' all start here. Companion: csharp (always, for any C#). For web front-end see frontend; for Ionic/Capacitor see mobile.4---56# dotnet (skill router)78The single source-of-truth index mapping a concrete .NET work area - a construct, command, file, or task - to the one focused skill to load. It routes, it does not restate: load the named skill for the actual guidance. Pick by what you are about to do; if several rows match, load several.910**Companion, not optional:** load `csharp` whenever you write or refactor any C# - naming, layout, modern syntax, async, dispose, exceptions/Result, logging, DI lifetimes. Every row below is *in addition to* the C# baseline, never instead of it.1112**Availability - required vs optional.** The always-on spine of any .NET work is three skills: this router, `csharp` (every `.cs` file), and `dotnet-testing` (the moment a test is written or changed - tests are part of the done gate). Add exactly one surface hub for the app under build - `dotnet-web-backend` (ASP.NET Core), `dotnet-console-apps` + `dotnet-hosted-services` (worker / CLI / bot / daemon), `dotnet-hosted-services` + `dotnet-windows-service` (a Windows Service under the SCM), or `dotnet-wpf` / `dotnet-winforms` (desktop). Every other row below is an optional specialist, loaded only when its area is in play - never up front - and installed only where the project's stack or evidence shows that area: a row whose skill is not in your skill list means the area is absent here, not a broken pointer - work from this router and skip the row.1314**The trigger is the artifact**, not 'am I doing .NET'. In a specific repo, that repo's `CLAUDE.md` binds these rows to its own file names and folders.1516## Language and types1718| You are about to... | Load |19|---|---|20| write or refactor any C# (naming, async, dispose, exceptions/Result, logging, DI lifetimes, modern syntax) | `csharp` (always) |21| add a `Channel<>`, `lock`, `SemaphoreSlim`, `Interlocked`, `Thread`, or other synchronization / producer-consumer code | `csharp` (its `references/concurrency.md`); a hosted worker's loop is `dotnet-hosted-services` |22| define a type where allocation or memory layout matters (struct vs class, `readonly struct`, pooling, `Span`) | `dotnet-performance` (its `references/type-design.md`) |23| (de)serialize JSON, reuse `JsonSerializerOptions`, or add a `JsonSerializerContext`, or pick a wire format (Protobuf/MessagePack) | `dotnet-performance` (its `references/serialization.md`) |24| author a Roslyn `IIncrementalGenerator`, or consume `[GeneratedRegex]` / `[LoggerMessage]` / `[JsonSerializable]` | `dotnet-source-generators` |25| choose or implement a GoF design pattern (factory, strategy, observer, undo/redo, plugin seams) or fix pattern misuse | `csharp-design-patterns` |2627## Architecture and structure2829| You are about to... | Load |30|---|---|31| model a domain type - aggregate, value object, domain event, strongly-typed ID | `dotnet-architecture` (its `references/ddd.md`) |32| decide which layer something belongs in, define a cross-layer port, or draw a module/service boundary | `dotnet-architecture` (the style decision + load-one rule live in its hub) |33| enforce layer / dependency / naming / isolation boundaries as automated tests (fitness functions) that fail the build | `dotnet-architecture-tests` |34| register services, build an `Add*` extension, or reason about DI lifetimes | `csharp` (lifetimes in the hub; `Add*` / keyed / factory composition in its `references/dependency-injection.md`) |35| bind or validate settings - `IOptions`, `IValidateOptions`, `ValidateOnStart` | `dotnet-web-backend` (its typed-options section) |36| set up a new solution - the layout, `.slnx`, `Directory.Build.props`, or `global.json` | `dotnet-project-setup` |37| add or upgrade a NuGet package, or edit `Directory.Packages.props` | `dotnet-project-setup` (its `references/central-package-management.md`) |38| set up or enforce C# formatting and analyzers - CSharpier, SDK analyzers, `.editorconfig` severity, `TreatWarningsAsErrors`, the CI quality gate | `dotnet-code-quality` |39| run a .NET migration workflow - EF schema, .NET/SDK version upgrade, or NuGet update with preview/rollback/verify | `dotnet-migrate` |4041## ASP.NET Core and web4243| You are about to... | Load |44|---|---|45| build any ASP.NET Core / Web API / microservice (cross-cutting baseline: HttpClient, resilience, versioning, observability, caching) | `dotnet-web-backend` (web hub - load first) |46| write minimal-API endpoint mechanics - `MapGroup`, `TypedResults`/`Results<>`, `IEndpointFilter`, parameter binding, file uploads | `dotnet-minimal-api` |47| write controller-based Web API mechanics - `[ApiController]`, attribute routing, `ActionResult<T>`, the automatic-400 filter, action filters, binding sources | `dotnet-mvc-controllers` |48| generate the OpenAPI document (Swashbuckle vs .NET 9 built-in, transformers, security schemes) or serve Scalar/Swagger UI | `dotnet-openapi` |49| map Result-to-HTTP, return RFC 9457 `ProblemDetails`, add a global `IExceptionHandler`, or validate via a FluentValidation endpoint filter | `dotnet-web-error-handling` |50| add authentication / authorization - JWT bearer, cookies, OIDC, ASP.NET Identity, policy-based authz, API keys | `dotnet-authentication` |51| build a gRPC service or client - `.proto` codegen, streaming modes, interceptors, status mapping, gRPC-Web | `dotnet-grpc` |52| push real-time updates to connected clients - SignalR hubs, strongly-typed `Hub<T>`, `IHubContext`, groups/presence, reconnection, Redis/Azure backplane scale-out | `dotnet-realtime` |5354## Cross-cutting hardening5556| You are about to... | Load |57|---|---|58| harden against OWASP Top 10 - injection, broken access control, SSRF, dependency audit, deprecated-security patterns | `dotnet-security` |59| use `System.Security.Cryptography` - hashing, AES-GCM, RSA/ECDSA, PBKDF2/Argon2id, constant-time compare | `dotnet-cryptography` |6061## Data and EF6263| You are about to... | Load |64|---|---|65| design or modify a schema, write SQL (raw or ORM), model a NoSQL doc, or create migrations / views / procs / indexes | `database-conventions` (data hub) |66| write EF Core / NHibernate data access - `Include`/`ThenInclude`, `AsSplitQuery`, `AsNoTracking`, query shaping | `dotnet-data-access` (its `references/efcore.md` or `references/nhibernate.md`) |67| diagnose ORM read-path performance - N+1, projection shape, change tracking, row count | `dotnet-data-access` (engine-side EXPLAIN / index / planner -> `postgres` or `sqlite`) |6869## Messaging and orchestration7071| You are about to... | Load |72|---|---|73| build broker-backed async messaging - Wolverine/MassTransit, transactional outbox, choreography vs sagas, message contracts | `dotnet-messaging` |74| wire local cloud-native orchestration - Aspire AppHost (`AddProject`/`AddPostgres`/`WithReference`/`WaitFor`), ServiceDefaults, dashboard | `dotnet-aspire` |7576## Hosting and background work7778| You are about to... | Load |79|---|---|80| write a worker service or in-process background task - `BackgroundService`/`IHostedService`, the `ExecuteAsync` exception trap, scoped services from the host, `PeriodicTimer`, graceful shutdown, `Channel<>`-backed work | `dotnet-hosted-services` |81| harden a long-running worker's outbound I/O - `HttpClient`/socket exhaustion, Polly v8 resilience, rate limiting, `ClientWebSocket` reconnect | `dotnet-hosted-services` (its `references/resilience-and-io.md`) |82| pick a scheduler (Hangfire / Quartz.NET / Coravel) or run a job on exactly one instance (leader election) | `dotnet-hosted-services` (its `references/scheduling-and-coordination.md`) |83| deploy or observe a headless worker - signals, systemd / container / Kubernetes shutdown, health checks without Kestrel, `[LoggerMessage]` | `dotnet-hosted-services` (its `references/deployment-and-observability.md`) |84| host a worker under the Windows Service Control Manager - `AddWindowsService` / `UseWindowsService`, SCM start/stop budgets and exit codes, scripted `sc.exe` install with recovery actions, service accounts, event-log source | `dotnet-windows-service` (load `dotnet-hosted-services` first - the host model it stacks on) |85| build a CLI tool - argument parsing (`System.CommandLine` 2.0 / `Spectre.Console.Cli` / `Cocona`), subcommands, exit codes | `dotnet-console-apps` |86| build a chat or trading bot - a Telegram / Discord / Slack / exchange SDK plugged into a `BackgroundService`, command handlers in DI | `dotnet-console-apps` (its `references/bot-sdks.md`) |8788## Testing and quality8990| You are about to... | Load |91|---|---|92| write, modify, or review .NET tests, or configure coverage (per-layer strategy, AAA, xUnit/NSubstitute/FluentAssertions) | `dotnet-testing` (test hub) |93| add container-backed integration tests | `dotnet-testing` (its `references/testcontainers.md`) |94| test an Aspire-orchestrated app end-to-end | `dotnet-testing` (its `references/aspire-integration-testing.md`) |95| add Verify / snapshot assertions | `dotnet-testing` (its `references/snapshot-testing.md`) |96| check a diff for reward-hacking / coverage-gaming shortcuts, or CRAP-score risk before claiming done | `dotnet-code-quality` (its reward-hacking list + `references/crap-analysis.md`) |9798## Diagnostics and performance99100| You are about to... | Load |101|---|---|102| add OpenTelemetry tracing / metrics instrumentation | `dotnet-web-backend` (wiring in the hub; manual spans / metrics in its `references/observability.md`) |103| write a microbenchmark (BenchmarkDotNet) | `dotnet-diagnostics` (its `references/microbenchmarking.md`) |104| capture or analyze a crash / hang dump | `dotnet-diagnostics` (its `references/dumps.md`) |105| inspect a compiled assembly's real API or behavior | `ilspy-decompile` |106| install or pin a .NET local tool (`dotnet tool` / manifest) | `dotnet-project-setup` (its `references/local-tools.md`) |107108## Desktop109110| You are about to... | Load |111|---|---|112| build a WPF desktop UI - strict MVVM, bindings, dependency/attached properties, async commands, `INotifyDataErrorInfo`, threading | `dotnet-wpf` |113| build or maintain a WinForms desktop UI - logic out of code-behind (MVP / the .NET 8 binding engine), control/component/GDI disposal, high-DPI, 4.8-vs-modern deltas | `dotnet-winforms` |114115## Legacy: .NET Framework 4.8 (net48)116117Maintaining or hardening a .NET Framework 4.8 codebase - the deltas from the modern floor live as a net48 reference inside each owner skill (`references/net-framework-48.md`, or the file the row names). Load the owner, then that file.118119| You are about to... | Load |120|---|---|121| write C# for net48 - the C# 7.3 language ceiling, compiler-only vs CLR-dependent features, polyfill packages, and the SynchronizationContext / ConfigureAwait async caveat | `csharp` (its `references/net-framework-48.md`) |122| harden a net48 app - TLS registry keys, BinaryFormatter still shipping, ViewState / machineKey rotation, classic-ASP.NET headers, web.config secrets, dependency auditing | `dotnet-security` (its `references/net-framework-48.md`) |123| use crypto on net48 - the PBKDF2 SHA-1 default, the RNG API name, AES-GCM availability | `dotnet-cryptography` (its `references/net-framework-48.md`) |124| optimize on net48 - the 'slow span', NuGet-only fast-path packages, benchmarking on net48 | `dotnet-performance` (its `references/net-framework-48.md`) |125| configure a net48 project - packages.config -> PackageReference, LangVersion pinning, Server GC, binding redirects | `dotnet-project-setup` (its `references/net-framework-48.md`) |126| migrate off net48 - the frozen-platform stance and the upgrade-vs-replace blocker map | `dotnet-migrate` (its `references/net-framework-48.md`) |127| build or maintain classic ASP.NET (MVC 5 / Web API 2 / Web Forms) on net48 - the single-threaded request context, no IHttpClientFactory, OWIN pipeline, caching | `dotnet-web-backend` (its `references/net-framework-48.md`) |128| wire MVC 5 / Web API 2 controllers - the two separate DI resolvers, bind-DTOs-not-entities, anti-forgery | `dotnet-mvc-controllers` (its `references/net-framework-48.md`) |129| add auth to classic ASP.NET - OWIN / Katana, ASP.NET Identity 2.x, OAuth bearer + JWT validation | `dotnet-authentication` (its `references/net-framework-48.md`) |130| pick and scope EF on net48 - EF Core 3.1 vs EF6, DbContext-per-request, the single-operation rule | `dotnet-data-access` (its `references/net-framework-48.md`) |131| test classic ASP.NET on net48 - in-memory OWIN TestServer, HttpContextBase over sealed HttpContext.Current | `dotnet-testing` (its `references/net-framework-48.md`) |132| build or maintain a WPF app on net48 - CommunityToolkit.Mvvm source-generator constraints, Generic Host composition, app-level exception handlers | `dotnet-wpf` (its `references/net-framework-48.md`) |133| maintain a .NET Framework Windows Service - the `ServiceBase` shape, `installutil`, and the migration path to `AddWindowsService` | `dotnet-windows-service` (its `references/framework-services.md`) |134135The async deadlock angle (why `ConfigureAwait(false)` is load-bearing here) is in `csharp`'s `references/net-framework-48.md`.136137## Notes138139- **Every target is house-owned.** This router points only to skills authored in this repo - hubs that carry a `references/` folder (`dotnet-architecture`, `dotnet-data-access`, `dotnet-project-setup`, `dotnet-performance`, `dotnet-diagnostics`) and the leaf specialists. Some rows route into a hub's reference file rather than a standalone skill - load the named skill and open that reference; nothing here installs from a third-party kit.140- **Hubs vs leaves.** `csharp` is the C# baseline hub, `dotnet-web-backend` the web hub, `database-conventions` the data hub, `dotnet-testing` the test hub - a leaf specialist points UP to its hub, the hub points DOWN to its deep specialists, and this router indexes them all. Load the web hub before a web specialist; load the data hub before EF/SQL specialists.141- **Out of this router's scope.** Web front-end work routes through `frontend` (and `mobile` for Ionic/Capacitor), not here. Cross-cutting flow that is not .NET-specific - `/security-review`, `project-verify-code`, context7 library docs, git - lives in the project's `CLAUDE.md`.