Repository: dotnet/aspnetcore
File: src/Components/Components/src/OwningComponentBase.cs (C#)

Code before:
        if (!IsDisposed)
        {
            if (disposing && _scope.HasValue && _scope.Value is IDisposable disposable)
            {
                disposable.Dispose();
                _scope = null;
            }

            IsDisposed = true;
        }
    }

    /// <inheritdoc />
    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (!IsDisposed)
        {
            try
            {
                await DisposeAsyncCore().ConfigureAwait(false);
            }
            finally
            {
                Dispose(disposing: true);
            }
        }
        GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Asynchronously releases the service scope used by the component.
    /// </summary>
    /// <returns>A task that represents the asynchronous dispose operation.</returns>
    protected virtual async ValueTask DisposeAsyncCore()
    {
        if (!IsDisposed && _scope.HasValue)
        {
            await _scope.Value.DisposeAsync().ConfigureAwait(false);
            _scope = null;
        }
    }
}

/// <summary>
/// A base class that creates a service provider scope, and resolves a service of type <typeparamref name="TService"/>.
/// </summary>
/// <typeparam name="TService">The service type.</typeparam>
/// <remarks>
/// Use the <see cref="OwningComponentBase{TService}"/> class as a base class to author components that control
/// the lifetime of a service or multiple services. This is useful when using a transient or scoped service that
/// requires disposal such as a repository or database abstraction. Using <see cref="OwningComponentBase{TService}"/>

Review comment (suggestion):
Not sure why we need the if here, that's already covered inside `DisposeAsyncCore`, same with the `try_finally`. It's overkill.

Code after:
        if (!IsDisposed)
        {
            if (disposing && _scope.HasValue && _scope.Value is IDisposable disposable)
            {
                disposable.Dispose();
                _scope = null;
            }

            IsDisposed = true;
        }
    }

    /// <inheritdoc />
    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        await DisposeAsyncCore().ConfigureAwait(false);

        Dispose(disposing: true);
        GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Asynchronously releases the service scope used by the component.
    /// </summary>
    /// <returns>A task that represents the asynchronous dispose operation.</returns>
    protected virtual async ValueTask DisposeAsyncCore()
    {
        if (!IsDisposed && _scope.HasValue)
        {
            await _scope.Value.DisposeAsync().ConfigureAwait(false);
            _scope = null;
        }
    }
}

/// <summary>
/// A base class that creates a service provider scope, and resolves a service of type <typeparamref name="TService"/>.
/// </summary>
/// <typeparam name="TService">The service type.</typeparam>
/// <remarks>
/// Use the <see cref="OwningComponentBase{TService}"/> class as a base class to author components that control
/// the lifetime of a service or multiple services. This is useful when using a transient or scoped service that
/// requires disposal such as a repository or database abstraction. Using <see cref="OwningComponentBase{TService}"/>
/// as a base class ensures that the service and relates services that share its scope are disposed with the component.
/// </remarks>
public abstract class OwningComponentBase<TService> : OwningComponentBase, IDisposable where TService : notnull
{
    private TService _item = default!;

    /// <summary>
    /// Gets the <typeparamref name="TService"/> that is associated with this component.