Skip to content

Commit c7933fd

Browse files
committed
SetBasePath earlier. Copy sources once
1 parent a52a3d3 commit c7933fd

File tree

4 files changed

+68
-35
lines changed

4 files changed

+68
-35
lines changed

src/DefaultBuilder/src/BootstrapHostBuilder.cs

+23-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ internal class BootstrapHostBuilder : IHostBuilder
1717
private readonly Configuration _configuration;
1818
private readonly WebHostEnvironment _environment;
1919

20+
private readonly List<Action<IConfigurationBuilder>> _configureHostActions = new List<Action<IConfigurationBuilder>>();
21+
private readonly List<Action<HostBuilderContext, IConfigurationBuilder>> _configureAppActions = new List<Action<HostBuilderContext, IConfigurationBuilder>>();
22+
2023
public BootstrapHostBuilder(Configuration configuration, WebHostEnvironment webHostEnvironment)
2124
{
2225
_configuration = configuration;
@@ -38,8 +41,7 @@ public IHost Build()
3841

3942
public IHostBuilder ConfigureAppConfiguration(Action<HostBuilderContext, IConfigurationBuilder> configureDelegate)
4043
{
41-
configureDelegate(_context, _configuration);
42-
_environment.ApplyConfigurationSettings(_configuration);
44+
_configureAppActions.Add(configureDelegate ?? throw new ArgumentNullException(nameof(configureDelegate)));
4345
return this;
4446
}
4547

@@ -52,8 +54,7 @@ public IHostBuilder ConfigureContainer<TContainerBuilder>(Action<HostBuilderCont
5254

5355
public IHostBuilder ConfigureHostConfiguration(Action<IConfigurationBuilder> configureDelegate)
5456
{
55-
configureDelegate(_configuration);
56-
_environment.ApplyConfigurationSettings(_configuration);
57+
_configureHostActions.Add(configureDelegate ?? throw new ArgumentNullException(nameof(configureDelegate)));
5758
return this;
5859
}
5960

@@ -66,7 +67,7 @@ public IHostBuilder ConfigureServices(Action<HostBuilderContext, IServiceCollect
6667

6768
public IHostBuilder UseServiceProviderFactory<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory) where TContainerBuilder : notnull
6869
{
69-
// This is not called by HostingHostBuilderExtensions.ConfigureDefaults currently, but that chould change in the future.
70+
// This is not called by HostingHostBuilderExtensions.ConfigureDefaults currently, but that could change in the future.
7071
// If this does get called in the future, it should be called again at a later stage on the ConfigureHostBuilder.
7172
return this;
7273
}
@@ -77,5 +78,22 @@ public IHostBuilder UseServiceProviderFactory<TContainerBuilder>(Func<HostBuilde
7778
// during the initial config stage. It should be called again later on the ConfigureHostBuilder.
7879
return this;
7980
}
81+
82+
internal void ExecuteActions()
83+
{
84+
foreach (var configureHostAction in _configureHostActions)
85+
{
86+
configureHostAction(_configuration);
87+
}
88+
89+
_environment.ApplyConfigurationSettings(_configuration);
90+
91+
foreach (var configureAppAction in _configureAppActions)
92+
{
93+
configureAppAction(_context, _configuration);
94+
}
95+
96+
_environment.ApplyConfigurationSettings(_configuration);
97+
}
8098
}
8199
}

src/DefaultBuilder/src/Configuration.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,15 @@ private ConfigurationRoot BuildConfigurationRoot()
9191
var providers = new List<IConfigurationProvider>();
9292
foreach (var source in _sources)
9393
{
94-
IConfigurationProvider provider = source.Build(this);
94+
var provider = source.Build(this);
9595
providers.Add(provider);
9696
}
9797
return new ConfigurationRoot(providers);
9898
}
9999

100100
private void RaiseChanged()
101101
{
102-
ConfigurationReloadToken previousToken = Interlocked.Exchange(ref _changeToken, new ConfigurationReloadToken());
102+
var previousToken = Interlocked.Exchange(ref _changeToken, new ConfigurationReloadToken());
103103
previousToken.OnReload();
104104
}
105105

src/DefaultBuilder/src/ConfigureHostBuilder.cs

+24-15
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,27 @@ public sealed class ConfigureHostBuilder : IHostBuilder
2020
/// <inheritdoc />
2121
public IDictionary<object, object> Properties { get; } = new Dictionary<object, object>();
2222

23-
internal Configuration Configuration => _configuration;
24-
25-
private readonly IConfigurationBuilder _hostConfiguration = new ConfigurationBuilder();
26-
2723
private readonly WebHostEnvironment _environment;
2824
private readonly Configuration _configuration;
2925
private readonly IServiceCollection _services;
3026

27+
private readonly HostBuilderContext _context;
28+
3129
internal ConfigureHostBuilder(Configuration configuration, WebHostEnvironment environment, IServiceCollection services)
3230
{
3331
_configuration = configuration;
3432
_environment = environment;
3533
_services = services;
34+
35+
_context = new HostBuilderContext(Properties)
36+
{
37+
Configuration = _configuration,
38+
HostingEnvironment = _environment
39+
};
3640
}
3741

42+
internal bool ConfigurationEnabled { get; set; }
43+
3844
IHost IHostBuilder.Build()
3945
{
4046
throw new NotSupportedException($"Call {nameof(WebApplicationBuilder)}.{nameof(WebApplicationBuilder.Build)}() instead.");
@@ -43,7 +49,13 @@ IHost IHostBuilder.Build()
4349
/// <inheritdoc />
4450
public IHostBuilder ConfigureAppConfiguration(Action<HostBuilderContext, IConfigurationBuilder> configureDelegate)
4551
{
46-
_operations += b => b.ConfigureAppConfiguration(configureDelegate);
52+
if (ConfigurationEnabled)
53+
{
54+
// Run these immediately so that they are observable by the imperative code
55+
configureDelegate(_context, _configuration);
56+
_environment.ApplyConfigurationSettings(_configuration);
57+
}
58+
4759
return this;
4860
}
4961

@@ -57,10 +69,12 @@ public IHostBuilder ConfigureContainer<TContainerBuilder>(Action<HostBuilderCont
5769
/// <inheritdoc />
5870
public IHostBuilder ConfigureHostConfiguration(Action<IConfigurationBuilder> configureDelegate)
5971
{
60-
// HACK: We need to evaluate the host configuration as they are changes so that we have an accurate view of the world
61-
configureDelegate(_hostConfiguration);
62-
63-
_environment.ApplyConfigurationSettings(_hostConfiguration.Build());
72+
if (ConfigurationEnabled)
73+
{
74+
// Run these immediately so that they are observable by the imperative code
75+
configureDelegate(_configuration);
76+
_environment.ApplyConfigurationSettings(_configuration);
77+
}
6478

6579
return this;
6680
}
@@ -69,12 +83,7 @@ public IHostBuilder ConfigureHostConfiguration(Action<IConfigurationBuilder> con
6983
public IHostBuilder ConfigureServices(Action<HostBuilderContext, IServiceCollection> configureDelegate)
7084
{
7185
// Run these immediately so that they are observable by the imperative code
72-
configureDelegate(new HostBuilderContext(Properties)
73-
{
74-
Configuration = Configuration,
75-
HostingEnvironment = _environment
76-
},
77-
_services);
86+
configureDelegate(_context, _services);
7887

7988
return this;
8089
}

src/DefaultBuilder/src/WebApplicationBuilder.cs

+19-13
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,29 @@ internal WebApplicationBuilder(Assembly? callingAssembly, string[]? args = null)
2929
// from the service collection before it is built. That needs to be fixed...
3030
Environment = _environment = new WebHostEnvironment(callingAssembly);
3131

32+
Configuration.SetBasePath(_environment.ContentRootPath);
3233
Services.AddSingleton(Environment);
3334

3435
// Run methods to configure both generic and web host defaults early to populate config from appsettings.json
3536
// environment variables (both DOTNET_ and ASPNETCORE_ prefixed) and other possible default sources to prepopulate
3637
// the correct defaults.
3738
var bootstrapBuilder = new BootstrapHostBuilder(Configuration, _environment);
38-
bootstrapBuilder.ConfigureWebHostDefaults(configure: _ => { });
3939
bootstrapBuilder.ConfigureDefaults(args);
40+
bootstrapBuilder.ConfigureWebHostDefaults(configure: _ => { });
41+
bootstrapBuilder.ExecuteActions();
4042

41-
Configuration.SetBasePath(_environment.ContentRootPath);
4243
Logging = new LoggingBuilder(Services);
4344
WebHost = _deferredWebHostBuilder = new ConfigureWebHostBuilder(Configuration, _environment, Services);
4445
Host = _deferredHostBuilder = new ConfigureHostBuilder(Configuration, _environment, Services);
4546

47+
// Register Configuration as IConfiguration so updates can be observed even after the WebApplication is built.
4648
Services.AddSingleton<IConfiguration>(Configuration);
4749

50+
// Add default services
4851
_deferredHostBuilder.ConfigureDefaults(args);
52+
// Configuration changes made by ConfigureDefaults(args) were already picked up by the BootstrapHostBuilder,
53+
// so we ignore changes to config until ConfigureDefaults completes.
54+
_deferredHostBuilder.ConfigurationEnabled = true;
4955
}
5056

5157
/// <summary>
@@ -158,17 +164,7 @@ private void ConfigureApplication(WebHostBuilderContext context, IApplicationBui
158164

159165
private void ConfigureWebHost(IWebHostBuilder genericWebHostBuilder)
160166
{
161-
genericWebHostBuilder.Configure(ConfigureApplication);
162-
163-
_hostBuilder.ConfigureServices((context, services) =>
164-
{
165-
foreach (var s in Services)
166-
{
167-
services.Add(s);
168-
}
169-
});
170-
171-
_hostBuilder.ConfigureAppConfiguration((hostContext, builder) =>
167+
_hostBuilder.ConfigureHostConfiguration(builder =>
172168
{
173169
// All the sources in builder.Sources should be in Configuration.Sources
174170
// already thanks to the BootstrapHostBuilder.
@@ -180,6 +176,16 @@ private void ConfigureWebHost(IWebHostBuilder genericWebHostBuilder)
180176
}
181177
});
182178

179+
_hostBuilder.ConfigureServices((context, services) =>
180+
{
181+
foreach (var s in Services)
182+
{
183+
services.Add(s);
184+
}
185+
});
186+
187+
genericWebHostBuilder.Configure(ConfigureApplication);
188+
183189
_deferredHostBuilder.ExecuteActions(_hostBuilder);
184190
_deferredWebHostBuilder.ExecuteActions(genericWebHostBuilder);
185191

0 commit comments

Comments
 (0)