Compile-time DI guardrails

DependencyInjection.Lifetime.Analyzers

Catch DI scope leaks, captive dependencies, BuildServiceProvider misuse, and unresolvable services before they become runtime bugs, flaky tests, or production-only failures.

Why teams install it

  • Find captive dependencies before stale state and thread-safety bugs ship.
  • Catch scope leaks before they become ObjectDisposedException incidents.
  • Detect missing registrations and implementation mismatches before runtime activation fails.
  • Push DI rules into CI instead of relying on reviewer memory.

Latest release

2.2.2

2026-03-17

  • DI015 Wrapper Reachability: DI015 now expands source-visible IServiceCollection wrapper extensions from real invocation sites instead of treating registrations inside uncalled wrappers as globally available.
  • DI015 Opaque Wrapper Suppression: Earlier opaque or external wrappers on the same IServiceCollection flow now suppress DI015 when registration state is uncertain, reducing false positives in layered registration modules.
  • DI015 Ordering and Flow Isolation: Wrapper-aware resolution now respects call order and per-collection flow, so wrappers invoked on a different IServiceCollection instance or after a registration do not hide genuine missing-dependency diagnostics.
  • DI015 Regression Coverage: Added should-report and should-not-report guardrails for invoked vs uninvoked wrappers, nested wrapper chains, cyclic wrappers, keyed mismatches, opaque external wrappers, same-method flow isolation, and registration ordering.

Featured diagnostics

High-intent landing pages for common DI bugs

View all rules

DI003

Captive Dependency

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.

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, or registration lambdas).

Severity: Warning · Code fix: No

DI001

Service Scope Not Disposed

`IServiceScope` instances created with `CreateScope()` or `CreateAsyncScope()` that are never disposed.

Severity: Warning · Code fix: Yes

Search-targeted pages

Common DI failure searches mapped to the right rules

See all problem guides

Problem guide

Spot Constructor Over-Injection Early

This rule is intentionally softer than runtime-failure diagnostics, but it is useful for preventing DI-heavy classes from becoming maintenance hotspots.

Problem guide

Use CreateAsyncScope In Async Methods

Use this rule when background services, async handlers, or hosted-service workflows are mixing sync scopes into async disposal paths.

Adoption

Roll it out without noise

Start with the default severities, promote high-confidence rules to errors, and use the sample-driven rule pages to explain the policy to the team.