Why it matters
global provider state encourages service locator use and muddles lifetime boundaries.
Leaving the school master key in the corridor means anybody can open any door at any time.
DI006
`IServiceProvider` / `IServiceScopeFactory` / keyed provider stored in static fields or properties.
Why it matters
global provider state encourages service locator use and muddles lifetime boundaries.
Leaving the school master key in the corridor means anybody can open any door at any time.
Install
dotnet add package DependencyInjection.Lifetime.Analyzers --version 2.2.2
README problem example
public static class Locator
{
public static IServiceProvider Provider { get; set; } = null!;
}
README better pattern
public sealed class Locator
{
private readonly IServiceProvider _provider;
public Locator(IServiceProvider provider)
{
_provider = provider;
}
}
Repo sample extraction
Sample app warning case
public class BadStaticProviderCache
{
// DI006: 'IServiceProvider' should not be stored in static member '_provider'
private static IServiceProvider? _provider;
// DI006: 'IServiceScopeFactory' should not be stored in static member '_scopeFactory'
private static IServiceScopeFactory? _scopeFactory;
// DI006: 'IServiceProvider' should not be stored in static member 'ServiceProvider'
public static IServiceProvider? ServiceProvider { get; set; }
public static void Initialize(IServiceProvider provider)
{
_provider = provider;
_scopeFactory = provider.GetRequiredService<IServiceScopeFactory>();
ServiceProvider = provider;
}
public static T? GetService<T>() where T : class
{
return _provider?.GetService<T>();
}
}
Sample app safe pattern
public class GoodInstanceProvider
{
private readonly IServiceProvider _provider;
public GoodInstanceProvider(IServiceProvider provider)
{
_provider = provider;
}
public T GetService<T>() where T : notnull
{
return _provider.GetRequiredService<T>();
}
}
Related guides
More documentation