Rules

Rule index

Browse all analyzer rules with rule summaries, README examples, and extracted sample-app snippets.

DI001

Service Scope Not Disposed

`IServiceScope` instances created with `CreateScope()` or `CreateAsyncScope()` that are never disposed, including scopes whose only disposal call is hidden behind a conditional branch, switch section, loop, catch block, or after a branch exit that can bypass shared cleanup. DI001 recognizes predeclared nullable scope locals assigned conditionally when a later conditional-access, non-null-guarded, same-branch pre-exit, or `finally` disposal reliably closes ownership, while still reporting reassignment leaks and loop-created scopes that need per-iteration disposal.

Severity: Warning · Code fix: Yes

DI002

Scoped Service Escapes Scope

a service resolved from a scope that is returned or stored somewhere longer-lived, including services resolved through provider aliases, delegates that capture scoped services and then escape, scopes disposed later via `using (scope)`, and the same patterns inside constructors, accessors, local functions, lambdas, and anonymous methods.

Severity: Warning · Code fix: Yes

DI003

Captive Dependency

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.

Severity: Warning · Code fix: Yes

DI004

Service Used After Scope Disposed

using a service after the scope that produced it has already ended, including services resolved through provider aliases, scoped collections from `GetServices<T>()` enumerated after disposal, explicit `Dispose()` / `DisposeAsync()`, scopes disposed later via `using (scope)`, and the same patterns inside constructors, accessors, local functions, lambdas, and anonymous methods.

Severity: Warning · Code fix: Yes

DI005

Use `CreateAsyncScope` in Async Methods

`CreateScope()` used in async flows where async disposal is needed, including async methods, lambdas, local functions, anonymous methods, and top-level programs that use `await`. Detection covers regular member access (`_scopeFactory.CreateScope()`) and conditional-access receivers (`_scopeFactory?.CreateScope()`, `_provider?.CreateScope()`) alike.

Severity: Warning · Code fix: Yes

DI006

Static `IServiceProvider` Cache

`IServiceProvider` / `IServiceScopeFactory` / keyed provider stored in static fields or properties, including `Lazy<T>` wrappers around those provider types.

Severity: Warning · Code fix: Yes

DI008

Disposable Transient Service

transient services implementing `IDisposable`/`IAsyncDisposable` in risky patterns.

Severity: Warning · Code fix: Yes

DI009

Open Generic Captive Dependency

open generic singleton registrations that depend on shorter-lived services, including `TryAddSingleton(...)`, `ServiceDescriptor.Singleton(...)`, keyed open-generic singleton registrations, and `IEnumerable<T>` constructor captures where the element service is shorter-lived.

Severity: Warning · Code fix: Yes

DI011

`IServiceProvider` Injection

constructor injection of `IServiceProvider`, `IServiceScopeFactory`, or `IKeyedServiceProvider` in normal services.

Severity: Info · Code fix: No

DI013

Implementation Type Mismatch

invalid service/implementation pairs that compile but fail at runtime, including generic, `typeof(...)`, keyed, named-argument, and `ServiceDescriptor` registrations.

Severity: Error · Code fix: Yes

DI014

Root Service Provider Not Disposed

root providers from `BuildServiceProvider()` that are never disposed, including local providers whose only manual disposal is conditional, catch-only, after reassignment to another provider, or after repeated creation inside a loop.

Severity: Warning · Code fix: Yes

DI015

Unresolvable Dependency

registered services with direct or transitive constructor/factory dependencies that are not registered (including keyed and open-generic paths).

Severity: Warning · Code fix: Yes

DI016

BuildServiceProvider Misuse

`BuildServiceProvider()` calls while composing registrations (for example in `ConfigureServices`, `IServiceCollection` extension registration methods, registration lambdas, or builder-style `.Services` helper flows).

Severity: Warning · Code fix: No

DI017

Circular Dependency

constructor-injection cycles such as `A -> B -> A`, including longer transitive loops. It stays silent when constructor selection is ambiguous rather than guessing which path the container will choose.

Severity: Warning · Code fix: No

DI018

Non-Instantiable Implementation Type

registrations whose implementation type cannot be constructed by the DI container, such as abstract classes, interfaces, static classes, delegate types registered without a factory, or concrete classes with no public constructors.

Severity: Warning · Code fix: No

DI019

Scoped Service Resolved From Root Provider

scoped services, known scoped framework services such as `IOptionsSnapshot<T>`, EF Core contexts from `AddDbContext(...)`, `AddDbContextFactory(...)`, `AddDbContextPool(...)`, and `AddPooledDbContextFactory(...)` including service/implementation overload self-registrations, or services whose activation graph reaches a scoped service, resolved from a root `IServiceProvider` such as ASP.NET Core `app.Services`, ASP.NET test-host `factory.Services` / `server.Services`, Generic Host `host.Services`, nullable root-provider surfaces such as `app.Services!`, or a provider returned by `BuildServiceProvider()`.

Severity: Warning · Code fix: No