Dispose configuration in WebHost (#9149)
Register the application configuration as a factory to make it dispose automatically when the service provider gets disposed. This will dispose the underlying configuration providers and change token registrations. The host configuration will be disposed implicitly when the chained configuration provider within the app configuration gets disposed.
This commit is contained in:
parent
28c5ed950b
commit
bcad853cbd
|
|
@ -175,6 +175,10 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
{
|
||||
host.Initialize();
|
||||
|
||||
// resolve configuration explicitly once to mark it as resolved within the
|
||||
// service provider, ensuring it will be properly disposed with the provider
|
||||
_ = host.Services.GetService<IConfiguration>();
|
||||
|
||||
var logger = host.Services.GetRequiredService<ILogger<WebHost>>();
|
||||
|
||||
// Warn about duplicate HostingStartupAssemblies
|
||||
|
|
@ -264,12 +268,13 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
|
||||
var builder = new ConfigurationBuilder()
|
||||
.SetBasePath(_hostingEnvironment.ContentRootPath)
|
||||
.AddConfiguration(_config);
|
||||
.AddConfiguration(_config, shouldDisposeConfiguration: true);
|
||||
|
||||
_configureAppConfigurationBuilder?.Invoke(_context, builder);
|
||||
|
||||
var configuration = builder.Build();
|
||||
services.AddSingleton<IConfiguration>(configuration);
|
||||
// register configuration as factory to make it dispose with the service provider
|
||||
services.AddSingleton<IConfiguration>(_ => configuration);
|
||||
_context.Configuration = configuration;
|
||||
|
||||
var listener = new DiagnosticListener("Microsoft.AspNetCore");
|
||||
|
|
|
|||
|
|
@ -975,6 +975,54 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
Assert.Contains("ConfigureServices", ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Dispose_DisposesAppConfiguration()
|
||||
{
|
||||
var providerMock = new Mock<ConfigurationProvider>().As<IDisposable>();
|
||||
providerMock.Setup(d => d.Dispose());
|
||||
|
||||
var sourceMock = new Mock<IConfigurationSource>();
|
||||
sourceMock.Setup(s => s.Build(It.IsAny<IConfigurationBuilder>()))
|
||||
.Returns((ConfigurationProvider)providerMock.Object);
|
||||
|
||||
var host = CreateBuilder()
|
||||
.ConfigureAppConfiguration(configuration =>
|
||||
{
|
||||
configuration.Add(sourceMock.Object);
|
||||
})
|
||||
.Build();
|
||||
|
||||
providerMock.Verify(c => c.Dispose(), Times.Never);
|
||||
|
||||
host.Dispose();
|
||||
|
||||
providerMock.Verify(c => c.Dispose(), Times.AtLeastOnce());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DisposeAsync_DisposesAppConfiguration()
|
||||
{
|
||||
var providerMock = new Mock<ConfigurationProvider>().As<IDisposable>();
|
||||
providerMock.Setup(d => d.Dispose());
|
||||
|
||||
var sourceMock = new Mock<IConfigurationSource>();
|
||||
sourceMock.Setup(s => s.Build(It.IsAny<IConfigurationBuilder>()))
|
||||
.Returns((ConfigurationProvider)providerMock.Object);
|
||||
|
||||
var host = CreateBuilder()
|
||||
.ConfigureAppConfiguration(configuration =>
|
||||
{
|
||||
configuration.Add(sourceMock.Object);
|
||||
})
|
||||
.Build();
|
||||
|
||||
providerMock.Verify(c => c.Dispose(), Times.Never);
|
||||
|
||||
await ((IAsyncDisposable)host).DisposeAsync();
|
||||
|
||||
providerMock.Verify(c => c.Dispose(), Times.AtLeastOnce());
|
||||
}
|
||||
|
||||
public class BadConfigureServicesStartup
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services, int gunk) { }
|
||||
|
|
|
|||
Loading…
Reference in New Issue