DI005

Use `CreateAsyncScope` in Async Methods

`CreateScope()` used in async flows where async disposal is needed.

Default severity: Warning · Code fix: Yes

Why it matters

async disposables (`IAsyncDisposable`) may not be cleaned up correctly with sync disposal patterns.

If a machine needs a proper shutdown button, pulling the plug is not enough.

README problem example

public async Task RunAsync()
{
    using var scope = _scopeFactory.CreateScope();
    var service = scope.ServiceProvider.GetRequiredService<IMyService>();
    await service.ExecuteAsync();
}

README better pattern

public async Task RunAsync()
{
    await using var scope = _scopeFactory.CreateAsyncScope();
    var service = scope.ServiceProvider.GetRequiredService<IMyService>();
    await service.ExecuteAsync();
}

Yes. Rewrites scope creation/disposal pattern.

Repo sample extraction

Examples pulled from the sample app

Open full sample file

Sample app warning case

    public async Task Bad_CreateScopeInAsyncMethod()
    {
        // DI005: Use 'CreateAsyncScope' instead of 'CreateScope' in async method
        using var scope = _scopeFactory.CreateScope();
        var service = scope.ServiceProvider.GetRequiredService<IScopedService>();
        await Task.Delay(100);
        service.DoWork();
    }

Sample app safe pattern

    public async Task Good_CreateAsyncScope()
    {
#pragma warning disable DI007 // Intentional use of IServiceProvider within a valid scope
        await using var scope = _scopeFactory.CreateAsyncScope();
        var service = scope.ServiceProvider.GetRequiredService<IScopedService>();
        await Task.Delay(100);
        service.DoWork();
#pragma warning restore DI007
    }