dotnet-opslisted
Install: claude install-skill AllThingsSmitty/agent-skills
# Production .NET Operations
ASP.NET Core is production-ready out of the box — but several defaults need explicit configuration before a service is truly operational: graceful shutdown, meaningful health checks, structured logging, and validated configuration. These aren't nice-to-haves; they're the difference between a service that degrades gracefully and one that drops requests during deploys.
## Graceful shutdown
.NET's generic host handles `SIGTERM` and `SIGINT` automatically — it triggers `IHostApplicationLifetime.ApplicationStopping` and waits for hosted services to stop. Configure the timeout:
```csharp
// Program.cs
builder.Services.Configure<HostOptions>(options =>
{
options.ShutdownTimeout = TimeSpan.FromSeconds(30);
});
```
For Kestrel (HTTP), in-flight requests are drained during shutdown. To stop accepting new connections while draining:
```csharp
var lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
lifetime.ApplicationStopping.Register(() =>
{
// Signal readiness probe to return 503 — stops new traffic from routing here
_isShuttingDown = true;
});
```
For custom resources (message consumers, database connections), implement `IHostedService`:
```csharp
public class MyConsumer : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await foreach (var message in _queue.ReadAsync(stoppingToken))
{
await ProcessAsync(message, stoppingToken);