disposal-and-resource-lifetimelisted
Install: claude install-skill Sarmkadan/dotnet-senior-skills
# Disposal and Resource Lifetime
## The ownership rule
Whoever creates a disposable disposes it; whoever receives one does not. Every review question about disposal reduces to "who owns this instance?"
- Created in a method: `using` / `await using`, no exceptions.
- Created in a constructor and stored in a field: the class owns it, so the class implements `IDisposable` and disposes the field.
- Injected via DI: the container owns it. Disposing an injected `DbContext` or typed `HttpClient` breaks the next consumer of the same scoped instance. A class whose only disposables are injected does not implement `IDisposable` at all.
```csharp
// WRONG: disposing what DI owns; second service in the scope gets a disposed context
public sealed class OrderService : IDisposable
{
private readonly AppDbContext _db;
public OrderService(AppDbContext db) => _db = db;
public void Dispose() => _db.Dispose();
}
// RIGHT: no IDisposable; the scope disposes the context
public sealed class OrderService
{
private readonly AppDbContext _db;
public OrderService(AppDbContext db) => _db = db;
}
```
## What must never be wrapped in using
- `HttpClient` from `IHttpClientFactory`: disposal is a no-op on the handler you care about, but `using` documents a false ownership. Sockets are managed by the factory's handler pool; `new HttpClient()` per call plus `using` is the classic socket-exhaustion bug (TIME_WAIT pileup under load).
- `CancellationTokenSource` still referenced by regis