77using Microsoft . Extensions . DependencyInjection ;
88using Microsoft . Extensions . Hosting ;
99using Microsoft . Extensions . Logging ;
10- using Microsoft . Extensions . Primitives ;
1110
1211namespace Microsoft . AspNetCore . Builder
1312{
@@ -16,11 +15,12 @@ namespace Microsoft.AspNetCore.Builder
1615 /// </summary>
1716 public sealed class WebApplicationBuilder
1817 {
18+ private const string EndpointRouteBuilderKey = "__EndpointRouteBuilder" ;
19+
1920 private readonly HostBuilder _hostBuilder = new ( ) ;
2021 private readonly BootstrapHostBuilder _bootstrapHostBuilder ;
2122 private readonly WebApplicationServiceCollection _services = new ( ) ;
2223 private readonly List < KeyValuePair < string , string > > _hostConfigurationValues ;
23- private const string EndpointRouteBuilderKey = "__EndpointRouteBuilder" ;
2424
2525 private WebApplication ? _builtApplication ;
2626
@@ -213,8 +213,20 @@ public WebApplication Build()
213213
214214 _builtApplication = new WebApplication ( _hostBuilder . Build ( ) ) ;
215215
216+ // We know that ConfigurationBuilder constructs ConfigurationRoot with a List<IConfigurationProvider> and all the
217+ // IgnoreLoadConfigurationProviders have been "loaded", so we can put the originals back.
218+ var providerList = ( List < IConfigurationProvider > ) ( ( IConfigurationRoot ) _builtApplication . Configuration ) . Providers ;
219+ for ( var i = 0 ; i < providerList . Count ; i ++ )
220+ {
221+ if ( providerList [ i ] is IgnoreLoadConfigurationProvider wrappedProvider )
222+ {
223+ providerList [ i ] = wrappedProvider . OriginalProvider ;
224+ }
225+ }
226+
216227 // Make builder.Configuration match the final configuration. To do that
217- // we clear the sources and add the built configuration as a source
228+ // we recreate the ConfigurationManager and add the built configuration as a source.
229+ // We do not clear or dispose the old ConfigurationManager as this would dispose IConfigurationProviders that are in use.
218230 Configuration = new ConfigurationManager ( ) ;
219231 Configuration . AddConfiguration ( _builtApplication . Configuration ) ;
220232
@@ -310,50 +322,10 @@ public ConfigurationProviderSource(IConfigurationProvider configurationProvider)
310322 {
311323 // ConfigurationManager has already loaded its IConfigurationProviders, so we do not need to load it again
312324 // during WebApplicationBuilder.Build(). See https://github.com/dotnet/aspnetcore/issues/37030
313- _configurationProvider = new IgnoreFirstLoadConfigurationProvider ( configurationProvider ) ;
325+ _configurationProvider = new IgnoreLoadConfigurationProvider ( configurationProvider ) ;
314326 }
315327
316328 public IConfigurationProvider Build ( IConfigurationBuilder builder ) => _configurationProvider ;
317-
318- private sealed class IgnoreFirstLoadConfigurationProvider : IConfigurationProvider , IDisposable
319- {
320- private readonly IConfigurationProvider _configurationProvider ;
321-
322- private bool _hasIgnoredFirstLoad ;
323-
324- public IgnoreFirstLoadConfigurationProvider ( IConfigurationProvider configurationProvider )
325- {
326- _configurationProvider = configurationProvider ;
327- }
328-
329- public void Load ( )
330- {
331- if ( ! _hasIgnoredFirstLoad )
332- {
333- _hasIgnoredFirstLoad = true ;
334- return ;
335- }
336-
337- _configurationProvider . Load ( ) ;
338- }
339-
340- public IChangeToken GetReloadToken ( ) => _configurationProvider . GetReloadToken ( ) ;
341-
342- public IEnumerable < string > GetChildKeys ( IEnumerable < string > earlierKeys , string parentPath ) =>
343- _configurationProvider . GetChildKeys ( earlierKeys , parentPath ) ;
344-
345- public void Set ( string key , string value ) => _configurationProvider . Set ( key , value ) ;
346-
347- public bool TryGet ( string key , out string value ) => _configurationProvider . TryGet ( key , out value ) ;
348-
349- public void Dispose ( ) => ( _configurationProvider as IDisposable ) ? . Dispose ( ) ;
350-
351- public override string ToString ( ) => _configurationProvider . ToString ( ) ! ;
352-
353- public override bool Equals ( object ? obj ) => _configurationProvider . Equals ( obj ) ;
354-
355- public override int GetHashCode ( ) => _configurationProvider . GetHashCode ( ) ;
356- }
357329 }
358330 }
359331}
0 commit comments