dotnet-10-csharp-14
π―Skillfrom mhagrelius/dotfiles
Modernizes .NET development with C# 14 best practices, minimal APIs, modular architecture, and advanced infrastructure patterns.
Installation
npx skills add https://github.com/mhagrelius/dotfiles --skill dotnet-10-csharp-14Skill Details
Use when building .NET 10 or C# 14 applications; when using minimal APIs, modular monolith patterns, or feature folders; when implementing HTTP resilience, Options pattern, Channels, or validation; when seeing outdated patterns like old extension method syntax
Overview
# .NET 10 & C# 14 Best Practices
.NET 10 (LTS, Nov 2025) with C# 14. Covers minimal APIs, not MVC.
Official docs: [.NET 10](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-10/overview) | [C# 14](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14) | [ASP.NET Core 10](https://learn.microsoft.com/en-us/aspnet/core/release-notes/aspnetcore-10.0)
Detail Files
| File | Topics |
|------|--------|
| [csharp-14.md](csharp-14.md) | Extension blocks, field keyword, null-conditional assignment |
| [minimal-apis.md](minimal-apis.md) | Validation, TypedResults, filters, modular monolith, vertical slices |
| [security.md](security.md) | JWT auth, CORS, rate limiting, OpenAPI security, middleware order |
| [infrastructure.md](infrastructure.md) | Options, resilience, channels, health checks, caching, Serilog, EF Core, keyed services |
| [testing.md](testing.md) | WebApplicationFactory, integration tests, auth testing |
| [anti-patterns.md](anti-patterns.md) | HttpClient, DI captive, blocking async, N+1 queries |
| [libraries.md](libraries.md) | MediatR, FluentValidation, Mapster, ErrorOr, Polly, Aspire |
---
Quick Start
```xml
```
```csharp
var builder = WebApplication.CreateBuilder(args);
// Core services
builder.Services.AddValidation();
builder.Services.AddProblemDetails();
builder.Services.AddOpenApi();
// Security
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
builder.Services.AddRateLimiter(opts => { / see security.md / });
// Infrastructure
builder.Services.AddHealthChecks();
builder.Services.AddOutputCache();
// Modules
builder.Services.AddUsersModule();
var app = builder.Build();
// Middleware (ORDER MATTERS - see security.md)
app.UseExceptionHandler();
app.UseHttpsRedirection();
app.UseCors();
app.UseRateLimiter();
app.UseAuthentication();
app.UseAuthorization();
app.UseOutputCache();
app.MapOpenApi();
app.MapHealthChecks("/health");
app.MapUsersEndpoints();
app.Run();
```
---
Decision Flowcharts
Result vs Exception
```dot
digraph {
"Error type?" [shape=diamond];
"Expected?" [shape=diamond];
"Result
"Exception" [shape=box];
"Error type?" -> "Expected?" [label="domain"];
"Error type?" -> "Exception" [label="infrastructure"];
"Expected?" -> "Result
"Expected?" -> "Exception" [label="no"];
}
```
IOptions Selection
```dot
digraph {
"Runtime changes?" [shape=diamond];
"Per-request?" [shape=diamond];
"IOptions
"IOptionsSnapshot
"IOptionsMonitor
"Runtime changes?" -> "IOptions
"Runtime changes?" -> "Per-request?" [label="yes"];
"Per-request?" -> "IOptionsSnapshot
"Per-request?" -> "IOptionsMonitor
}
```
Channel Type
```dot
digraph {
"Trust producer?" [shape=diamond];
"Can drop?" [shape=diamond];
"Bounded+Wait" [shape=box,style=filled,fillcolor=lightgreen];
"Bounded+Drop" [shape=box];
"Unbounded" [shape=box];
"Trust producer?" -> "Unbounded" [label="yes"];
"Trust producer?" -> "Can drop?" [label="no"];
"Can drop?" -> "Bounded+Drop" [label="yes"];
"Can drop?" -> "Bounded+Wait" [label="no"];
}
```
---
Key Patterns Summary
C# 14 Extension Blocks
```csharp
extension
{
public bool IsEmpty => !source.Any();
}
```
.NET 10 Built-in Validation
```csharp
builder.Services.AddValidation();
app.MapPost("/users", (UserDto dto) => TypedResults.Ok(dto));
```
TypedResults (Always Use)
```csharp
app.MapGet("/users/{id}", async (int id, IUserService svc) =>
await svc.GetAsync(id) is { } user
? TypedResults.Ok(user)
: TypedResults.NotFound());
```
Module Pattern
```csharp
public static class UsersModule
{
public static IServiceCollection AddUsersModule(this IServiceCollection s) => s
.AddScoped
public static IEndpointRouteBuilder MapUsersEndpoints(this IEndpointRouteBuilder app)
{
var g = app.MapGroup("/api/users").WithTags("Users");
g.MapGet("/{id}", GetUser.Handle);
return app;
}
}
```
HTTP Resilience
```csharp
builder.Services.AddHttpClient
.AddStandardResilienceHandler();
```
Error Handling (RFC 9457)
```csharp
builder.Services.AddProblemDetails();
app.UseExceptionHandler();
app.UseStatusCodePages();
```
---
MANDATORY Patterns (Always Use These)
| Task | β ALWAYS Use | β NEVER Use |
|------|--------------|--------------|
| Extension members | C# 14 extension blocks | Traditional this extension methods |
| Property validation | C# 14 field keyword | Manual backing fields |
| Null assignment | obj?.Prop = value | if (obj != null) obj.Prop = value |
| API returns | TypedResults.Ok() | Results.Ok() |
| Options validation | .ValidateOnStart() | Missing validation |
| HTTP resilience | AddStandardResilienceHandler() | Manual Polly configuration |
| Timestamps | DateTime.UtcNow | DateTime.Now |
---
Quick Reference Card
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β .NET 10 / C# 14 PATTERNS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β EXTENSION PROPERTY: extension
β public bool IsEmpty => !s.Any(); β
β } β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β FIELD KEYWORD: public string Name { β
β get => field; β
β set => field = value?.Trim(); β
β } β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β OPTIONS VALIDATION: .BindConfiguration(Section) β
β .ValidateDataAnnotations() β
β .ValidateOnStart(); // CRITICAL! β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β HTTP RESILIENCE: .AddStandardResilienceHandler(); β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β TYPED RESULTS: TypedResults.Ok(data) β
β TypedResults.NotFound() β
β TypedResults.Created(uri, data) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ERROR PATTERN: ErrorOr
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β IOPTIONS: IOptions
β IOptionsSnapshot
β IOptionsMonitor
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
---
Anti-Patterns Quick Reference
| Anti-Pattern | Fix |
|--------------|-----|
| new HttpClient() | Inject HttpClient or IHttpClientFactory |
| Results.Ok() | TypedResults.Ok() |
| Manual Polly config | AddStandardResilienceHandler() |
| Singleton β Scoped | Use IServiceScopeFactory |
| GetAsync().Result | await GetAsync() |
| Exceptions for flow | Use ErrorOr Result pattern |
| DateTime.Now | DateTime.UtcNow |
| Missing .ValidateOnStart() | Always add to Options registration |
See [anti-patterns.md](anti-patterns.md) for complete list.
---
Libraries Quick Reference
| Library | Package | Purpose |
|---------|---------|---------|
| MediatR | MediatR | CQRS |
| FluentValidation | FluentValidation.DependencyInjectionExtensions | Validation |
| Mapster | Mapster.DependencyInjection | Mapping |
| ErrorOr | ErrorOr | Result pattern |
| Polly | Microsoft.Extensions.Http.Resilience | Resilience |
| Serilog | Serilog.AspNetCore | Logging |
See [libraries.md](libraries.md) for usage examples.
More from this repository8
Helps debug and configure .NET Aspire distributed applications, resolving service discovery, environment, deployment, and polyglot integration challenges.
Enables precise Python code navigation and type checking using pyright-lsp, finding references, definitions, and verifying type correctness semantically.
Builds interactive terminal user interfaces (TUIs) with responsive layouts, keyboard navigation, and real-time data updates across multiple programming languages.
Guides developers in creating robust, Unix-philosophy-aligned command-line interface tools with best practices for argument parsing, stream handling, and cross-language implementation.
Transcribes YouTube video content, extracting spoken text from videos for quick understanding and analysis.
Helps developers architect and debug GTK 4/libadwaita applications by addressing lifecycle, threading, resource management, and packaging challenges.
Designs GNOME user interfaces with precision, ensuring Human Interface Guidelines compliance and modern libadwaita styling.
Enables semantic code intelligence for TypeScript/JavaScript, providing accurate references, type checking, definition navigation, and symbol understanding.