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 and high-confidence factory paths such as inline delegates, method-group factories, 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.2.2
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