Why it matters
lifetime mismatch can produce stale state, leaks, and thread-safety defects.
If one pupil keeps the shared class scissors all term, nobody else can use them when needed.
DI003
singleton services capturing scoped or transient dependencies, including constructor injection, `IEnumerable<T>` collection captures, known scoped framework services such as `IOptionsSnapshot<T>`, EF Core contexts and `DbContextOptions<TContext>` registrations from `AddDbContext(...)`, `AddDbContextFactory(...)`, `AddDbContextPool(...)`, and `AddPooledDbContextFactory(...)` including service/implementation overload self-registrations, and high-confidence factory paths such as inline delegates, stable local delegate factories, method-group factories, `GetServices<T>()`, keyed resolutions, and `ActivatorUtilities.CreateInstance(...)` without explicit constructor arguments.
Why it matters
lifetime mismatch can produce stale state, leaks, and thread-safety defects.
If one pupil keeps the shared class scissors all term, nobody else can use them when needed.
Install
dotnet add package DependencyInjection.Lifetime.Analyzers --version 2.8.26
README problem example
services.AddScoped<IScopedService, ScopedService>();
services.AddSingleton<ISingletonService, SingletonService>();
public sealed class SingletonService : ISingletonService
{
public SingletonService(IScopedService scoped) { }
}
README better pattern
services.AddScoped<ISingletonService, SingletonService>();
// or keep singleton and create scopes inside operations
public sealed class SingletonService : ISingletonService
{
private readonly IServiceScopeFactory _scopeFactory;
public SingletonService(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public void Run()
{
using var scope = _scopeFactory.CreateScope();
var scoped = scope.ServiceProvider.GetRequiredService<IScopedService>();
scoped.DoWork();
}
}
Repo sample extraction
Sample app warning case
public class BadSingletonWithScopedDependency
{
private readonly IScopedService _scopedService;
// DI003: Singleton 'BadSingletonWithScopedDependency' captures scoped dependency 'IScopedService'
public BadSingletonWithScopedDependency(IScopedService scopedService)
{
_scopedService = scopedService;
}
public void DoWork() => _scopedService.DoWork();
}
Sample app safe pattern
public class GoodSingletonWithScopeFactory
{
private readonly IServiceScopeFactory _scopeFactory;
public GoodSingletonWithScopeFactory(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public void DoWork()
{
#pragma warning disable DI007 // Factory pattern - IServiceScopeFactory is allowed to resolve services
using var scope = _scopeFactory.CreateScope();
var scopedService = scope.ServiceProvider.GetRequiredService<IScopedService>();
scopedService.DoWork();
#pragma warning restore DI007
}
}
Related guides
More documentation