Why it matters
disposal ownership can become unclear and resources may be leaked.
Borrowing a bike every minute without returning the old one fills the whole bike shed.
DI008
transient services implementing `IDisposable`/`IAsyncDisposable` in risky patterns.
Why it matters
disposal ownership can become unclear and resources may be leaked.
Borrowing a bike every minute without returning the old one fills the whole bike shed.
Install
dotnet add package DependencyInjection.Lifetime.Analyzers --version 2.2.2
README problem example
services.AddTransient<IMyService, DisposableService>();
public sealed class DisposableService : IMyService, IDisposable
{
public void Dispose() { }
}
README better pattern
services.AddScoped<IMyService, DisposableService>();
// or ensure explicit disposal ownership if transient is intentional
Repo sample extraction
Sample app warning case
public class BadDisposableTransient : IDisposableService, IDisposable
{
private bool _disposed;
public void DoWork()
{
if (_disposed) throw new ObjectDisposedException(nameof(BadDisposableTransient));
// Do work...
}
public void Dispose()
{
_disposed = true;
// Resources will NOT be cleaned up because container doesn't track transients
}
}
Sample app safe pattern
public class GoodScopedDisposable : IScopedDisposable
{
private bool _disposed;
public void DoWork()
{
if (_disposed) throw new ObjectDisposedException(nameof(GoodScopedDisposable));
// Do work...
}
public void Dispose()
{
_disposed = true;
// Container WILL call this when the scope is disposed
}
}
Related guides
More documentation