Skip to content
Back to skills

Dotnet Patterns

ASecurity

Use when writing C#/.NET backend code — ASP.NET Core APIs (minimal APIs or MVC), workers, EF Core data access. Builder playbook: layout, DI lifetimes, async/cancellation, EF Core discipline, options pattern, error contract, testing shape. Complements csharp-reviewer.

  • 8 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 1, 2026
ai-agentsc#dockertestingapidatabasebackend

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 1, 2026

npx -y skills add jdanigo/hydraia --skill dotnet-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dotnet Patterns?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Dotnet Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jdanigo-dotnet-patterns/badge)](https://www.skillsdirectory.com/skills/jdanigo-dotnet-patterns)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: dotnet-patterns
description: Use when writing C#/.NET backend code — ASP.NET Core APIs (minimal APIs or MVC), workers, EF Core data access. Builder playbook: layout, DI lifetimes, async/cancellation, EF Core discipline, options pattern, error contract, testing shape. Complements csharp-reviewer.
---

# C#/.NET Backend Patterns

## Layout

- Vertical slices (feature folders: endpoint + handler + models per feature) for API-shaped services; full Clean Architecture layering only when the domain genuinely warrants it — record the choice as an ADR either way.
- Minimal APIs for small/medium surfaces; MVC controllers when filters/model-binding complexity earns it.

## DI lifetimes (the classic traps)

- Scoped services must NEVER be captured by singletons (captive dependency — resolve via `IServiceScopeFactory` inside the singleton instead).
- `HttpClient` via `IHttpClientFactory`, never `new HttpClient()` per call (socket exhaustion).
- Register by interface at the boundary you intend to fake in tests; concrete elsewhere is fine.

## Async all the way

- No `.Result`/`.Wait()`/`GetAwaiter().GetResult()` on async paths — deadlock and threadpool starvation fuel.
- `CancellationToken` flows from the endpoint through every service and EF call: `await db.Orders.ToListAsync(ct)`. Endpoints accept it; libraries propagate it.
- `ValueTask` only where profiling justifies it; default is `Task`.

## EF Core discipline

- Reads: `AsNoTracking()` by default; project to DTOs with `Select` — never return entities from queries that don't update.
- No lazy-loading proxies: load explicitly (`Include`) so every query's shape is visible — N+1 becomes impossible to miss.
- Migrations: one migration per change, reviewed like code; destructive column changes follow expand-contract (see db-optimization skill).
- Transactions explicit where multi-write consistency matters (`ExecutionStrategy` + `TransactionScope`-free patterns with `BeginTransactionAsync`).

## Config — options pattern

- `IOptions<T>` with `ValidateDataAnnotations().ValidateOnStart()` — invalid config fails the boot, not the first request.
- Secrets from user-secrets/KeyVault/env — never appsettings committed values.

## Error contract

- `ProblemDetails` (RFC 9457) via `AddProblemDetails()`; exceptions mapped centrally (exception handler middleware), typed domain exceptions → status codes. No try/catch per controller.
- Nullable reference types ON project-wide; warnings as errors for new code.

## Testing shape

- xUnit; unit tests fake at the interface boundary.
- `WebApplicationFactory<Program>` for integration tests over the real pipeline (routing, filters, serialization) with a test database (Testcontainers where Docker exists).
- Snapshot the API surface where the contract matters (Verify/ApiApprovals) so drift is a failing test.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…