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(). Root-provider aliases also stay classified through ?? throw guards and conditional expressions whose two result arms are proven root through path-stable declarations or straight-line writes. Provider declarations and assignments are collected in source order, path stability propagates through copied aliases, later unclassified, ??=, deconstruction, and ref/out writes invalidate older provider facts. Write facts become visible only after right-hand-side, initializer, or argument evaluation, and nested mutation events are processed before their enclosing write, so resolutions and alias copies observe the provider state at that runtime point. Assignments in the always-evaluated left operand of &&, ||, or ??, in a ternary's always-evaluated condition, and in the governing expression of a switch statement or switch expression retain path stability; matching right-operand writes, ternary result-arm writes, and writes in switch sections or result arms stay conservative because execution can skip them. Nested ternary-arm, short-circuit-right, and null-conditional WhenNotNull writes remain conditional even inside a switch governing expression, while a write in the null-conditional receiver remains definite. Merely binding or retargeting a ref local preserves the referents' facts; source-positioned mappings ensure later writes follow every possible storage active at that point across conditional or unconditional retargeting and ref-conditional local, by-reference argument, or lvalue targets, while reads use only the mapping active at their position and classify the alias only when every possible storage agrees. Writes through aliases with multiple possible referents invalidate every candidate storage rather than claiming each one definitely received the new value. Forward or backward goto edges cannot make path-dependent facts stable. Field/property facts never qualify because source position cannot prove cross-method execution; deferred lambda, LINQ-query, and local-function hazards remain conservative for captured outer storage, while locals and parameters owned by the deferred boundary retain ordinary path stability for declarations and straight-line writes. Control flow outside that owning boundary does not alter the path executed inside it. Other control-flow-dependent, mixed root/scoped, and unknown arms stay conservative. Both ordinary extension syntax and direct static calls through the exact framework ServiceProviderServiceExtensions and ServiceProviderKeyedServiceExtensions types are analyzed, including reordered named arguments; same-named user extensions stay silent.
Warning Default severity · Code fix: Yes