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 Dispose(true) cleanup, and caller-owned return flows are accepted even when the BuildServiceProvider() result is parenthesized, same-instance cast, null-forgiven, selected by a ternary arm, or supplied by a null-coalescing operand — including a provider stored in a local and returned later (ownership transfer), and create-and-dispose within the same loop iteration, switch section, or catch clause (a continue/break that skips the dispose still reports). A using declaration or statement proves cleanup only when that same provider instance reaches its resource expression. User-defined conversions remain reportable because they may produce a different instance, including a disposable wrapper selected by a coalesce inside using.

Warning Default severity · Code fix: Yes

Why it matters

Singleton disposables at root scope may never be cleaned up.

Locking the front door but leaving all the taps running still wastes the whole house.

README problem example

var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
var service = provider.GetRequiredService<IMyService>();

README better pattern

using var provider = services.BuildServiceProvider();
var service = provider.GetRequiredService<IMyService>();

Yes. Adds disposal pattern for simple local declarations with no existing manual disposal code; declared types that do not implement the required disposal interface (e.g. IServiceProvider) are rewritten to var so the emitted using compiles. Conditional or otherwise partial manual-disposal flows stay diagnostic-only so the ownership rewrite remains deliberate.

Repo sample extraction

Examples pulled from the sample app

Open full sample file

Sample app warning case

    public void BadExample()
    {
        var services = new ServiceCollection();
        
        // ⚠️ BAD: Root provider is not disposed
        // Disposable singletons will not be disposed
        var provider = services.BuildServiceProvider();
        
        var service = provider.GetService<IServiceScopeFactory>();
    }

Sample app safe pattern

    public void GoodExample()
    {
        var services = new ServiceCollection();

        // ✅ GOOD: Provider disposed via 'using'
        using var provider = services.BuildServiceProvider();
        
        var service = provider.GetService<IServiceScopeFactory>();
    }

Nearby diagnostics

Other rules in this family

All 37 rules