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

Code before:
            if (ScopeFactory == null)
            {
                throw new InvalidOperationException("Services cannot be accessed before the component is initialized.");
            }

            ObjectDisposedException.ThrowIf(IsDisposed, this);

            _scope ??= ScopeFactory.CreateAsyncScope();
            return _scope.Value.ServiceProvider;
        }
    }

    /// <summary>
    /// Releases the service scope used by the component.
    /// </summary>
    void IDisposable.Dispose()
    {
        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>
    public async ValueTask DisposeAsync()
    {
        await DisposeAsyncCore().ConfigureAwait(false);

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

    /// <summary>
    /// Releases the service scope used by the component.
    /// </summary>
    /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
    protected virtual void Dispose(bool disposing)
    {
        if (!IsDisposed)
        {
            if (disposing)
            {
                if (_scope.HasValue)
                {
                    if (_scope.Value is IDisposable disposable)
                    {
                        disposable.Dispose();
                    }
                    _scope = null;
                }

Review comment (suggestion):
Make the implementation private. Like the one for Dispose.

https://github.com/dotnet/aspnetcore/pull/62583/files#diff-82e944331c19e7b8ef290d4273e29da3e222ac5ed6df259a5d06de8dceaba6d0R50

To make an interface implementation private, you remove public and put the interface name right before the method `(in this case IAsyncDisposable.DisposeAsync)`

Code after:
            if (ScopeFactory == null)
            {
                throw new InvalidOperationException("Services cannot be accessed before the component is initialized.");
            }

            ObjectDisposedException.ThrowIf(IsDisposed, this);

            _scope ??= ScopeFactory.CreateAsyncScope();
            return _scope.Value.ServiceProvider;
        }
    }

    /// <inhertidoc />
    void IDisposable.Dispose()
    {
        Dispose(disposing: true);
        GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Releases the service scope used by the component.
    /// </summary>
    /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
    protected virtual void Dispose(bool disposing)
    {
        if (!IsDisposed)
        {
            if (disposing && _scope.HasValue && _scope.Value is IDisposable disposable)
            {
                disposable.Dispose();
                _scope = null;
            }

            IsDisposed = true;
        }
    }

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

        Dispose(disposing: false);
        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()