Dispose the host if Initialize fails (#1324)

This commit is contained in:
David Fowler 2018-01-31 16:00:55 -08:00 committed by GitHub
parent 86989413f6
commit f8d61a4c52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 4 deletions

View File

@ -100,7 +100,7 @@ namespace Microsoft.AspNetCore.Hosting
throw new ArgumentNullException(nameof(configureServices));
}
return ConfigureServices((_ , services) => configureServices(services));
return ConfigureServices((_, services) => configureServices(services));
}
/// <summary>
@ -189,10 +189,19 @@ namespace Microsoft.AspNetCore.Hosting
_options,
_config,
hostingStartupErrors);
try
{
host.Initialize();
host.Initialize();
return host;
return host;
}
catch
{
// Dispose the host if there's a failure to initialize, this should clean up
// will dispose services that were constructed until the exception was thrown
host.Dispose();
throw;
}
}
private IServiceCollection BuildCommonServices(out AggregateException hostingStartupErrors)

View File

@ -369,6 +369,23 @@ namespace Microsoft.AspNetCore.Hosting
Assert.Equal("A public method named 'ConfigureProduction' or 'Configure' could not be found in the 'Microsoft.AspNetCore.Hosting.Fakes.StartupBoom' type.", exception.Message);
}
[Fact]
public void ServiceProviderDisposedOnBuildException()
{
var service = new DisposableService();
var hostBuilder = new WebHostBuilder()
.UseServer(new TestServer())
.ConfigureServices(services =>
{
// Added as a factory since instances are never disposed by the container
services.AddSingleton(sp => service);
})
.UseStartup<StartupWithResolvedDisposableThatThrows>();
Assert.Throws<InvalidOperationException>(() => hostBuilder.Build());
Assert.True(service.Disposed);
}
[Fact]
public void CaptureStartupErrorsHonored()
{
@ -1050,6 +1067,16 @@ namespace Microsoft.AspNetCore.Hosting
}
}
public class DisposableService : IDisposable
{
public bool Disposed { get; private set; }
public void Dispose()
{
Disposed = true;
}
}
public class TestHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
@ -1068,6 +1095,24 @@ namespace Microsoft.AspNetCore.Hosting
}
}
public class StartupWithResolvedDisposableThatThrows
{
public StartupWithResolvedDisposableThatThrows(DisposableService service)
{
}
public void ConfigureServices(IServiceCollection services)
{
throw new InvalidOperationException();
}
public void Configure(IApplicationBuilder app)
{
}
}
public class TestLoggerProvider : ILoggerProvider
{
public TestSink Sink { get; set; } = new TestSink();