---
description: ASP.NET Core Patterns
alwaysApply: false
---

# ASP.NET Core Patterns

Modern ASP.NET Core. Minimal APIs, middleware, and production-grade patterns.

## Minimal APIs

```csharp
var group = app.MapGroup("/orders").RequireAuthorization();
group.MapGet("/{id:int}", GetOrderById);
group.MapPost("/", CreateOrder);
group.MapDelete("/{id:int}", DeleteOrder).RequireAuthorization("AdminOnly");
```

## Endpoint Pattern

```csharp
private static async Task<IResult> CreateOrder(
    CreateOrderRequest req, IValidator<CreateOrderRequest> v,
    IOrderService svc, CancellationToken ct) {
    var val = await v.ValidateAsync(req, ct);
    if (!val.IsValid) return Results.ValidationProblem(val.ToDictionary());
    return (await svc.CreateAsync(req, ct)).Match(
        order => Results.Created($"/orders/{order.Id}", order),
        error => Results.Problem(error.Message, statusCode: 400));
}
```

## Health Checks

```csharp
builder.Services.AddHealthChecks()
    .AddDbContextCheck<AppDbContext>("database")
    .AddRedis(connStr, "redis");
app.MapHealthChecks("/healthz");
```

## Rate Limiting

```csharp
builder.Services.AddRateLimiter(o => o.AddFixedWindowLimiter("api", c => {
    c.PermitLimit = 100; c.Window = TimeSpan.FromMinutes(1);
}));
app.UseRateLimiter();
```

## Configuration

Use Options pattern: `AddOptions<T>().BindConfiguration().ValidateDataAnnotations().ValidateOnStart()`

## Background Services

```csharp
public class ProcessorService(IServiceScopeFactory sf, ILogger<ProcessorService> log)
    : BackgroundService {
    protected override async Task ExecuteAsync(CancellationToken ct) {
        while (!ct.IsCancellationRequested) {
            using var scope = sf.CreateScope();
            try {
                await scope.ServiceProvider.GetRequiredService<IProcessor>().ProcessAsync(ct);
            } catch (Exception ex) when (ex is not OperationCanceledException) {
                log.LogError(ex, "Processing error");
            }
            await Task.Delay(TimeSpan.FromSeconds(30), ct);
        }
    }
}
```

## Anti-Patterns

- **Business logic in endpoints** — keep endpoints thin, delegate to services
- **Exposing entities directly** — always map to DTOs/response records
- **Synchronous I/O in middleware** — use async file/network operations
