Comparison
Why put DI rules in the build?
Use this matrix when deciding what belongs in compile-time diagnostics versus runtime validation or manual review.
| Concern | DependencyInjection.Lifetime.Analyzers | Runtime container validation | Code review only |
|---|---|---|---|
| Captive dependencies and lifetime mismatch | Flags singleton-to-scoped/transient capture in IDE and CI. | Usually discovered only under load, stale-state bugs, or production behavior. | Easy to miss when registrations and constructors are far apart. |
| Scope leaks and use-after-dispose | Finds undisposed scopes, escapes, and use-after-dispose paths before runtime. | Often surfaces as ObjectDisposedException or memory leaks after deployment. | Reviewers need to reason about scope boundaries manually. |
| Missing registrations and bad implementation types | Reports unresolved dependencies and incompatible registrations at compile time. | Startup or activation throws once the path is exercised. | Hard to validate transitive constructor graphs by inspection. |
| BuildServiceProvider misuse during registration | Stops accidental second-container creation in composition code. | Can remain hidden until subtle lifetime bugs or duplicate singletons appear. | Often slips in as a convenient workaround. |
| Service locator drift and IServiceProvider injection | Keeps direct provider usage visible with Info-level guidance or stronger policies. | No runtime guardrail unless behavior fails elsewhere. | Frequently normalized over time unless explicitly enforced. |