# DependencyInjection.Lifetime.Analyzers > Roslyn analyzer package for Microsoft.Extensions.DependencyInjection. It reports dependency > injection lifetime bugs at compile time — captive dependencies, scope leaks, undisposed scopes, > BuildServiceProvider misuse, service locator drift, unresolvable and circular registrations — > in Visual Studio, Rider, and dotnet build. It adds no runtime dependency and stays quiet when > a bug cannot be proven statically. Version 3.7.8. Install: `dotnet add package DependencyInjection.Lifetime.Analyzers --version 3.7.8` (reference it with `PrivateAssets="all"`). ## Rules - [DI001: Service Scope Not Disposed](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/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, or behind a switch section, loop, or catch block that does not also contain the creation, or after a branch exit that… - [DI002: Scoped Service Escapes Scope](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di002-scoped-service-escapes-scope/): A service resolved from a tracked IServiceScope with a known scoped registration that is returned or stored beyond that scope. The tracked scope shapes are direct CreateScope()/CreateAsyncScope() calls and existing scope locals later disposed in the same executable boundary. The rule follows the… - [DI003: Captive Dependency](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di003-captive-dependency/): Singleton services capturing scoped or transient dependencies, including constructor injection, IEnumerable collection captures, known scoped framework services such as IOptionsSnapshot, typed HTTP clients registered with AddHttpClient() / AddHttpClient()… - [DI004: Service Used After Scope Disposed](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di004-service-used-after-scope-disposed/): Using a service after the scope that produced it has already ended, including scoped collections from GetServices() enumerated after disposal, explicit Dispose() / DisposeAsync() (including scope?.Dispose() for scope locals), wrapped use receivers such as service!.DoWork() and… - [DI005: Use `CreateAsyncScope` in Async Methods](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di005-use-createasyncscope-in-async-methods/): CreateScope() used in async flows where async disposal is needed and CreateAsyncScope() is available, including async methods, lambdas, local functions, anonymous methods, and top-level programs that use await. Detection covers regular member access (_scopeFactory.CreateScope()), parameterless… - [DI006: Static `IServiceProvider` Cache](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di006-static-iserviceprovider-cache/): IServiceProvider / IServiceScopeFactory / keyed provider stored in static fields or properties, including common wrappers (Lazy, Task, ValueTask, Func, AsyncLocal, ThreadLocal), mutable/immutable/frozen dictionary value caches, recursive dictionary values such as… - [DI007: Service Locator Anti-Pattern](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di007-service-locator-anti-pattern/): Resolving dependencies via IServiceProvider inside app logic, including non-generic resolution calls that pass a local Type alias initialized from typeof(...). - [DI008: Disposable Transient Service](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di008-disposable-transient-service/): Transient services implementing IDisposable/IAsyncDisposable in risky patterns. - [DI009: Open Generic Captive Dependency](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di009-open-generic-captive-dependency/): Open generic singleton registrations that depend on shorter-lived services, including common registration-shape variants such as TryAddSingleton(...), ServiceDescriptor.Singleton(...), keyed open-generic singleton registrations, and IEnumerable constructor captures where the element service… - [DI010: Constructor Over-Injection](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di010-constructor-over-injection/): Constructors with too many meaningful dependencies. - [DI011: `IServiceProvider` Injection](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di011-iserviceprovider-injection/): Constructor injection of IServiceProvider, IServiceScopeFactory, or IKeyedServiceProvider in normal services. - [DI012: Conditional Registration Misuse](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di012-conditional-registration-misuse/): - TryAdd* calls after an Add* already registered that service. - [DI013: Implementation Type Mismatch](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di013-implementation-type-mismatch/): Invalid service/implementation pairs that compile but fail at runtime, including generic, typeof(...), keyed, named-argument, and ServiceDescriptor registrations. Closed-type compatibility follows CLR assignability — identity, reference, boxing, and T → Nullable — so implicit numeric… - [DI014: Root Service Provider Not Disposed](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/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. Straight-line explicit disposal, standard Dispose() to… - [DI015: Unresolvable Dependency](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di015-unresolvable-dependency/): Registered services with direct or transitive constructor/factory dependencies that are not registered (including keyed and open-generic paths). - [DI016: BuildServiceProvider Misuse](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di016-buildserviceprovider-misuse/): BuildServiceProvider() calls while composing registrations (for example in ConfigureServices, IServiceCollection extension registration methods, registration lambdas, or builder-style .Services helper flows), whether written as reduced extension syntax (services.BuildServiceProvider()) or as a… - [DI017: Circular Dependency](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di017-circular-dependency/): High-confidence activation cycles such as A -> B -> A, including longer transitive loops through constructors, explicit GetRequiredService / GetRequiredKeyedService factory calls, ActivatorUtilities factory construction, keyed-service inheritance, open-generic registrations, exact closed… - [DI018: Non-Instantiable Implementation Type](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/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, default structs and enums, or concrete classes with no public constructors. - [DI019: Scoped Service Resolved From Root Provider](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di019-scoped-service-resolved-from-root-provider/): Scoped services, known scoped framework services such as IOptionsSnapshot, EF Core contexts from AddDbContext(...), AddDbContextFactory(...), AddDbContextPool(...), and AddPooledDbContextFactory(...) including service/implementation overload self-registrations, or services whose activation… - [DI020: Middleware Captures Scoped Service In Constructor](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di020-middleware-captures-scoped-service-in-constructor/): Scoped services captured by the constructor of a conventional middleware class — both directly (a scoped parameter) and transitively (a parameter whose activation graph reaches a scoped service). Middleware registrations are recognized in reduced extension form (app.UseMiddleware()) and in… - [DI021: Non-Thread-Safe Service Shared Across Concurrent Handler Invocations](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di021-non-thread-safe-service-shared-across-concurrent-handler-invocations/): A documented non-thread-safe service (EF Core DbContext and derived contexts, DbConnection/DbCommand/DbTransaction/DbDataReader and their interfaces, IDbContextTransaction, HttpContext) created or resolved once and then captured — through a field, a closure over an outer local, or an enclosing… - [DI022: Service Instance Reused Across Handler Invocations](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di022-service-instance-reused-across-handler-invocations/): Two tiers. First, the same capture shape as DI021 on a sink whose concurrency is controlled by a configuration knob that cannot be proven at compile time — canonically ServiceBusProcessor where MaxConcurrentCalls comes from configuration or is left at its default of 1, and RabbitMQ consumers… - [DI023: Fire-and-Forget Background Work Captures a Scope](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di023-fire-and-forget-background-work-captures-a-scope/): A using scope, a local bound to its ServiceProvider, or any local resolved from it, captured by background work started with Task.Run or TaskFactory.StartNew whose task is thrown away — an expression statement, a _ = discard, or a finite/cancelable Wait(...) whose Boolean result is stored or… - [DI024: Hosted Service Creates Scope Outside Execution Loop](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di024-hosted-service-creates-scope-outside-execution-loop/): Two tiers. First, a BackgroundService.ExecuteAsync override or IHostedService/IHostedLifecycleService start method that creates an IServiceScope once before its long-running execution loop (while (!token.IsCancellationRequested), compound cancellation conditions, while (true), for (;;)… - [DI025: Event Subscription On Longer-Lived Publisher Without Unsubscribe](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di025-event-subscription-on-longer-lived-publisher-without-unsubscribe/): A transient- or scoped-registered service that subscribes (+=) an instance-capturing handler — an instance method group, a this-capturing lambda, or a stored instance-bound delegate field — to an event on a longer-lived publisher and never unsubscribes. Subscriber lifetime is evaluated per… - [DI026: Event Subscription On Scoped Publisher Without Unsubscribe](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di026-event-subscription-on-scoped-publisher-without-unsubscribe/): The scope-bounded tier of DI025: a transient-registered service subscribes an instance-capturing handler to an event on a scoped registered publisher — the receiver, identity/reference-cast, handler, and unsubscription proofs are exactly DI025's — and never unsubscribes. Publisher lifetime… - [DI027: Rx Subscription On Longer-Lived Observable Without Dispose](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di027-rx-subscription-on-longer-lived-observable-without-dispose/): The Rx twin of DI025. IObservable.Subscribe(...) returns an IDisposable token that unsubscribes the observer when disposed, so there is no -= to prove missing — the leak proof inverts to a discarded token. A transient or scoped registered service subscribes an instance-capturing handler… - [DI028: Discarded Callback Registration On A Longer-Lived Source](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di028-discarded-callback-registration-on-a-longer-lived-source/): The third member of the DI025/DI027 family. Where DI025 proves a missing -= and DI027 proves a discarded Subscribe token, DI028 covers every remaining way .NET hands out a callback registration: IOptionsMonitor.OnChange, CancellationToken.Register / UnsafeRegister, ChangeToken.OnChange… - [DI029: HttpClient Lifetime Misuse](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di029-httpclient-lifetime-misuse/): Two opposite lifetime errors on the same connection pool. Socket exhaustion — a registered service constructs new HttpClient(...) on a per-invocation path (a method, accessor, lambda, any loop body, or the constructor of a transient service). Stale DNS — an HttpClient is handed to the container… - [DI030: Unbounded Singleton Or Static Cache](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di030-unbounded-singleton-or-static-cache/): Two shapes of a store that never shrinks. Unbounded growth — a private field of a concrete mutable collection (ConcurrentDictionary<,>, Dictionary<,>, List<>, HashSet<>, Queue<>, ConcurrentBag<>, ConcurrentQueue<>) that is static or owned by a singleton-registered service, written on a… - [DI031: Shared Implementation Registered Under Several Service Types](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di031-shared-implementation-registered-under-several-service-types/): One implementation type registered under two or more different service types with the same singleton or scoped lifetime, as plain type registrations on the same service-collection flow. - [DI032: Service Implements Only IAsyncDisposable](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di032-service-implements-only-iasyncdisposable/): A service the container creates — a plain type registration at any lifetime — whose implementation implements IAsyncDisposable but not IDisposable. - [DI033: Container Will Not Dispose a Pre-Built Instance](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di033-container-will-not-dispose-a-pre-built-instance/): A disposable instance handed to the container as an existing object — AddSingleton(new Thing()) or a descriptor carrying an implementation instance. - [DI034: HttpContext Used in Fire-and-Forget Background Work](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di034-httpcontext-used-in-fire-and-forget-background-work/): An HttpContext value — a parameter, local, or field of that type — or a read of IHttpContextAccessor.HttpContext, inside background work started with Task.Run or TaskFactory.StartNew whose task is thrown away or observed only through a finite/cancelable Wait(...) Boolean result. - [DI035: Non-Thread-Safe Service Shared Across a Fan-Out](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di035-non-thread-safe-service-shared-across-a-fan-out/): A documented non-thread-safe service — an EF Core DbContext or a derived context, IDbContextTransaction, or an ADO.NET connection, command, transaction, or reader — declared outside a Task.WhenAll projection and used inside every one of its tasks. This includes a service created once per outer… - [DI036: Registration Added After The Provider Was Built](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di036-registration-added-after-the-provider-was-built/): A call that mutates an IServiceCollection — AddSingleton, TryAddScoped, Configure, Replace, Add(descriptor), any AddXxx/TryAddXxx extension — executed after a provider was already built from that same collection in the same method. The build is either BuildServiceProvider() on the collection or… - [DI037: Un-awaited Task Escapes The Scope That Created It](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/di037-un-awaited-task-escapes-the-scope-that-created-it/): A task started on a service resolved from a using service scope and then allowed to leave that scope without being awaited — returned to the caller, discarded with _ = or as a bare statement, assigned to a field or property, or collected into a list declared outside the scope to be awaited after… ## Problem guides - [Fix ObjectDisposedException From Scoped Services](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/problems/objectdisposedexception-from-scoped-service/): Compile-time guidance for scope leaks, services escaping scopes, and using resolved services after the scope ends in ASP.NET Core and .NET apps. - [Find Captive Dependencies In ASP.NET Core](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/problems/captive-dependency-in-aspnet-core/): Use compile-time diagnostics to catch singleton-to-scoped and singleton-to-transient lifetime mismatches before stale state or thread-safety bugs ship. - [Avoid BuildServiceProvider In ConfigureServices](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/problems/avoid-buildserviceprovider-in-configureservices/): Catch BuildServiceProvider misuse during service registration so composition code does not silently create a second service container. - [Catch Unable To Resolve Service For Type Failures Earlier](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/problems/unable-to-resolve-service-for-type/): Find missing registrations and implementation mismatches at compile time instead of learning about them from runtime activation exceptions. - [Reduce IServiceProvider Injection And Service Locator Usage](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/problems/iserviceprovider-injection-and-service-locator/): Surface hidden dependencies, service locator drift, and direct IServiceProvider injection in application code before it hardens into architecture debt. - [Catch Disposable Transient Service Registrations](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/problems/disposable-transient-service/): Identify transient services implementing IDisposable or IAsyncDisposable that the container will not track or dispose automatically. - [Spot Constructor Over-Injection Early](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/problems/constructor-over-injection/): Find classes that are accumulating too many constructor dependencies so SRP drift shows up in IDE diagnostics and CI instead of code-review debates. - [Detect TryAdd And Duplicate Registration Misuse](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/problems/conditional-registration-and-tryadd-misuse/): Catch ignored TryAdd calls and duplicate registrations that change single-service resolution behavior in Microsoft.Extensions.DependencyInjection. - [Use CreateAsyncScope In Async Methods](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/problems/createasyncscope-in-async-methods/): Catch CreateScope usage in async flows so async-disposable services are cleaned up with the correct scope pattern. ## Reference - [Rule index](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/rules/): every diagnostic with default severity and code-fix availability. - [Adoption guide](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/adoption/): staged rollout and severity configuration. - [Comparison](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/compare/): how static analysis differs from runtime scope validation and code review. - [Latest release](https://georgepwall1991.github.io/DependencyInjection.Lifetime.Analyzers/releases/latest/): current release notes. - [Source](https://github.com/georgepwall1991/DependencyInjection.Lifetime.Analyzers): analyzer implementation, tests, and sample app.