architecture/dependency-injection

dependency injection Shipped

What this lens looks for

Confirm dependencies arrive via constructor injection through Microsoft.Extensions.DependencyInjection, and that each injected dependency is typed as an interface rather than a concrete class; check lifetime selection — Transient for lightweight stateless services, Scoped for per-request services, Singleton for thread-safe shared state — and flag mismatches; watch for the captive-dependency anti-pattern where a Scoped (or Transient) service is injected into a Singleton, capturing the shorter lifetime; confirm configuration is bound through IOptions<T> / IOptionsSnapshot<T> rather than raw config access; confirm service registrations are organized into Add*() extension methods on IServiceCollection for modularity rather than scattered inline at the composition root.

What its verifier checks

Every dependency is supplied by constructor injection (no service-locator or property injection); injected dependencies are declared as interface types, not concrete types; each service is registered with a lifetime appropriate to its role (Transient stateless, Scoped per-request, Singleton thread-safe shared state); no scoped or transient service is injected into a singleton (no captive dependency); configuration is bound via IOptions<T> / IOptionsSnapshot<T>; registrations live in Add*() extension methods rather than inline.