Skip to content

Commit

Permalink
Add the ConfigurationManager to the IServiceCollection (dotnet#36832) (
Browse files Browse the repository at this point in the history
…dotnet#36864)

- Add an IConfiguration to the service collection for scenarios where uses end up prematurely building the service provider or sniffing the IServiceCollection for it. We then remove the ConfigurationManager reference it from the final IServiceCollection to avoid cycles in the configuration graph that result in stack overflows (we link the configuration manager to the final configuration that has been built).
- Added tests
  • Loading branch information
davidfowl authored Sep 23, 2021
1 parent ac0a387 commit 87894e2
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/DefaultBuilder/src/WebApplicationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ internal WebApplicationBuilder(WebApplicationOptions options, Action<IHostBuilde
Logging = new LoggingBuilder(Services);
Host = new ConfigureHostBuilder(hostContext, Configuration, Services);
WebHost = new ConfigureWebHostBuilder(webHostContext, Configuration, Services);

Services.AddSingleton<IConfiguration>(Configuration);
}

/// <summary>
Expand Down Expand Up @@ -171,6 +173,17 @@ public WebApplication Build()
// we called ConfigureWebHostDefaults on both the _deferredHostBuilder and _hostBuilder.
foreach (var s in _services)
{
// Skip the configuration manager instance we added earlier
// we're already going to wire it up to this new configuration source
// after we've built the application. There's a chance the user manually added
// this as well but we still need to remove it from the final configuration
// to avoid cycles in the configuration graph
if (s.ServiceType == typeof(IConfiguration) &&
s.ImplementationInstance == Configuration)
{
continue;
}

services.Add(s);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,39 @@ public async Task WebApplicationConfiguration_HostFilterOptionsAreReloadable()
Assert.Contains("NewHost", options.AllowedHosts);
}

[Fact]
public void CanResolveIConfigurationBeforeBuildingApplication()
{
var builder = WebApplication.CreateBuilder();
var sp = builder.Services.BuildServiceProvider();

var config = sp.GetService<IConfiguration>();
Assert.NotNull(config);
Assert.Same(config, builder.Configuration);

var app = builder.Build();

// These are different
Assert.NotSame(app.Configuration, builder.Configuration);
}

[Fact]
public void ManuallyAddingConfigurationAsServiceWorks()
{
var builder = WebApplication.CreateBuilder();
builder.Services.AddSingleton<IConfiguration>(builder.Configuration);
var sp = builder.Services.BuildServiceProvider();

var config = sp.GetService<IConfiguration>();
Assert.NotNull(config);
Assert.Same(config, builder.Configuration);

var app = builder.Build();

// These are different
Assert.NotSame(app.Configuration, builder.Configuration);
}

[Fact]
public async Task WebApplicationConfiguration_EnablesForwardedHeadersFromConfig()
{
Expand Down

0 comments on commit 87894e2

Please sign in to comment.