Dispose DI scope with async support in circuit host

Fixes part of #12918

This fixes the part of this issue that we're going to be able to do in
3.0 safely.
This commit is contained in:
Ryan Nowak 2019-08-14 13:40:17 -07:00
parent e5a950de97
commit 13fc89ce49
2 changed files with 39 additions and 1 deletions

View File

@ -170,7 +170,18 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
try
{
Renderer.Dispose();
_scope.Dispose();
// This cast is needed because it's possible the scope may not support async dispose.
// Our DI container does, but other DI systems may not.
if (_scope is IAsyncDisposable asyncDisposable)
{
await asyncDisposable.DisposeAsync();
}
else
{
_scope.Dispose();
}
Log.DisposeSucceeded(_logger, CircuitId);
}
catch (Exception ex)

View File

@ -39,6 +39,33 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
Assert.Null(circuitHost.Handle.CircuitHost);
}
[Fact]
public async Task DisposeAsync_DisposesScopeAsynchronouslyIfPossible()
{
// Arrange
var serviceScope = new Mock<IServiceScope>();
serviceScope
.As<IAsyncDisposable>()
.Setup(f => f.DisposeAsync())
.Returns(new ValueTask(Task.CompletedTask))
.Verifiable();
var remoteRenderer = GetRemoteRenderer();
var circuitHost = TestCircuitHost.Create(
Guid.NewGuid().ToString(),
serviceScope.Object,
remoteRenderer);
// Act
await circuitHost.DisposeAsync();
// Assert
serviceScope.Verify(s => s.Dispose(), Times.Never());
serviceScope.As<IAsyncDisposable>().Verify(s => s.DisposeAsync(), Times.Once());
Assert.True(remoteRenderer.Disposed);
Assert.Null(circuitHost.Handle.CircuitHost);
}
[Fact]
public async Task DisposeAsync_DisposesResourcesAndSilencesException()
{