2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
4
using System . Diagnostics ;
5
+ using System . Diagnostics . CodeAnalysis ;
5
6
using System . Reflection ;
6
7
using Microsoft . AspNetCore . Authentication ;
7
8
using Microsoft . AspNetCore . Authorization ;
@@ -75,17 +76,7 @@ internal WebApplicationBuilder(WebApplicationOptions options, Action<IHostBuilde
75
76
options . SuppressEnvironmentConfiguration = true ;
76
77
} ) ;
77
78
78
- // This applies the config from ConfigureWebHostDefaults
79
- // Grab the GenericWebHostService ServiceDescriptor so we can append it after any user-added IHostedServices during Build();
80
- _genericWebHostServiceDescriptor = bootstrapHostBuilder . RunDefaultCallbacks ( ) ;
81
-
82
- // Grab the WebHostBuilderContext from the property bag to use in the ConfigureWebHostBuilder. Then
83
- // grab the IWebHostEnvironment from the webHostContext. This also matches the instance in the IServiceCollection.
84
- var webHostContext = ( WebHostBuilderContext ) bootstrapHostBuilder . Properties [ typeof ( WebHostBuilderContext ) ] ;
85
- Environment = webHostContext . HostingEnvironment ;
86
-
87
- Host = new ConfigureHostBuilder ( bootstrapHostBuilder . Context , Configuration , Services ) ;
88
- WebHost = new ConfigureWebHostBuilder ( webHostContext , Configuration , Services ) ;
79
+ _genericWebHostServiceDescriptor = InitializeHosting ( bootstrapHostBuilder ) ;
89
80
}
90
81
91
82
internal WebApplicationBuilder ( WebApplicationOptions options , bool slim , Action < IHostBuilder > ? configureDefaults = null )
@@ -138,7 +129,7 @@ internal WebApplicationBuilder(WebApplicationOptions options, bool slim, Action<
138
129
bootstrapHostBuilder . ConfigureSlimWebHost (
139
130
webHostBuilder =>
140
131
{
141
- AspNetCore . WebHost . ConfigureWebDefaultsCore ( webHostBuilder ) ;
132
+ AspNetCore . WebHost . ConfigureWebDefaultsSlim ( webHostBuilder ) ;
142
133
143
134
// Runs inline.
144
135
webHostBuilder . Configure ( ConfigureApplication ) ;
@@ -154,9 +145,74 @@ internal WebApplicationBuilder(WebApplicationOptions options, bool slim, Action<
154
145
options . SuppressEnvironmentConfiguration = true ;
155
146
} ) ;
156
147
148
+ _genericWebHostServiceDescriptor = InitializeHosting ( bootstrapHostBuilder ) ;
149
+ }
150
+
151
+ internal WebApplicationBuilder ( WebApplicationOptions options , bool slim , bool empty , Action < IHostBuilder > ? configureDefaults = null )
152
+ {
153
+ Debug . Assert ( ! slim , "should only be called with slim: false" ) ;
154
+ Debug . Assert ( empty , "should only be called with empty: true" ) ;
155
+
156
+ var configuration = new ConfigurationManager ( ) ;
157
+
158
+ // empty builder should still default the ContentRoot as usual. This is the expected behavior for all WebApplicationBuilders.
159
+ SetDefaultContentRoot ( options , configuration ) ;
160
+
161
+ _hostApplicationBuilder = Microsoft . Extensions . Hosting . Host . CreateEmptyApplicationBuilder ( new HostApplicationBuilderSettings
162
+ {
163
+ Args = options . Args ,
164
+ ApplicationName = options . ApplicationName ,
165
+ EnvironmentName = options . EnvironmentName ,
166
+ ContentRootPath = options . ContentRootPath ,
167
+ Configuration = configuration ,
168
+ } ) ;
169
+
170
+ // Set WebRootPath if necessary
171
+ if ( options . WebRootPath is not null )
172
+ {
173
+ Configuration . AddInMemoryCollection ( new [ ]
174
+ {
175
+ new KeyValuePair < string , string ? > ( WebHostDefaults . WebRootKey , options . WebRootPath ) ,
176
+ } ) ;
177
+ }
178
+
179
+ // Run methods to configure web host defaults early to populate services
180
+ var bootstrapHostBuilder = new BootstrapHostBuilder ( _hostApplicationBuilder ) ;
181
+
182
+ // This is for testing purposes
183
+ configureDefaults ? . Invoke ( bootstrapHostBuilder ) ;
184
+
185
+ bootstrapHostBuilder . ConfigureSlimWebHost (
186
+ webHostBuilder =>
187
+ {
188
+ AspNetCore . WebHost . ConfigureWebDefaultsEmpty ( webHostBuilder ) ;
189
+
190
+ // Runs inline.
191
+ webHostBuilder . Configure ( ( context , app ) => ConfigureApplication ( context , app , allowDeveloperExceptionPage : false ) ) ;
192
+
193
+ webHostBuilder . UseSetting ( WebHostDefaults . ApplicationKey , _hostApplicationBuilder . Environment . ApplicationName ?? "" ) ;
194
+
195
+ // NOTE: There is no way to add Configuration before this gets called, so it is unnecessary
196
+ // to set the following properties from the Configuration:
197
+ // - WebHostDefaults.PreventHostingStartupKey
198
+ // - WebHostDefaults.HostingStartupAssembliesKey
199
+ // - WebHostDefaults.HostingStartupExcludeAssembliesKey
200
+ } ,
201
+ options =>
202
+ {
203
+ // This is an "empty" builder, so don't add the "ASPNETCORE_" environment variables
204
+ options . SuppressEnvironmentConfiguration = true ;
205
+ } ) ;
206
+
207
+ _genericWebHostServiceDescriptor = InitializeHosting ( bootstrapHostBuilder ) ;
208
+ }
209
+
210
+ [ MemberNotNull ( nameof ( Environment ) , nameof ( Host ) , nameof ( WebHost ) ) ]
211
+ private ServiceDescriptor InitializeHosting ( BootstrapHostBuilder bootstrapHostBuilder )
212
+ {
157
213
// This applies the config from ConfigureWebHostDefaults
158
214
// Grab the GenericWebHostService ServiceDescriptor so we can append it after any user-added IHostedServices during Build();
159
- _genericWebHostServiceDescriptor = bootstrapHostBuilder . RunDefaultCallbacks ( ) ;
215
+ var genericWebHostServiceDescriptor = bootstrapHostBuilder . RunDefaultCallbacks ( ) ;
160
216
161
217
// Grab the WebHostBuilderContext from the property bag to use in the ConfigureWebHostBuilder. Then
162
218
// grab the IWebHostEnvironment from the webHostContext. This also matches the instance in the IServiceCollection.
@@ -165,6 +221,8 @@ internal WebApplicationBuilder(WebApplicationOptions options, bool slim, Action<
165
221
166
222
Host = new ConfigureHostBuilder ( bootstrapHostBuilder . Context , Configuration , Services ) ;
167
223
WebHost = new ConfigureWebHostBuilder ( webHostContext , Configuration , Services ) ;
224
+
225
+ return genericWebHostServiceDescriptor ;
168
226
}
169
227
170
228
private static DefaultServiceProviderFactory GetServiceProviderFactory ( HostApplicationBuilder hostApplicationBuilder )
@@ -272,7 +330,7 @@ private static void AddDefaultServicesSlim(ConfigurationManager configuration, I
272
330
/// <summary>
273
331
/// Provides information about the web hosting environment an application is running.
274
332
/// </summary>
275
- public IWebHostEnvironment Environment { get ; }
333
+ public IWebHostEnvironment Environment { get ; private set ; }
276
334
277
335
/// <summary>
278
336
/// A collection of services for the application to compose. This is useful for adding user provided or framework provided services.
@@ -293,13 +351,13 @@ private static void AddDefaultServicesSlim(ConfigurationManager configuration, I
293
351
/// An <see cref="IWebHostBuilder"/> for configuring server specific properties, but not building.
294
352
/// To build after configuration, call <see cref="Build"/>.
295
353
/// </summary>
296
- public ConfigureWebHostBuilder WebHost { get ; }
354
+ public ConfigureWebHostBuilder WebHost { get ; private set ; }
297
355
298
356
/// <summary>
299
357
/// An <see cref="IHostBuilder"/> for configuring host specific properties, but not building.
300
358
/// To build after configuration, call <see cref="Build"/>.
301
359
/// </summary>
302
- public ConfigureHostBuilder Host { get ; }
360
+ public ConfigureHostBuilder Host { get ; private set ; }
303
361
304
362
IDictionary < object , object > IHostApplicationBuilder . Properties => ( ( IHostApplicationBuilder ) _hostApplicationBuilder ) . Properties ;
305
363
@@ -321,7 +379,10 @@ public WebApplication Build()
321
379
return _builtApplication ;
322
380
}
323
381
324
- private void ConfigureApplication ( WebHostBuilderContext context , IApplicationBuilder app )
382
+ private void ConfigureApplication ( WebHostBuilderContext context , IApplicationBuilder app ) =>
383
+ ConfigureApplication ( context , app , allowDeveloperExceptionPage : true ) ;
384
+
385
+ private void ConfigureApplication ( WebHostBuilderContext context , IApplicationBuilder app , bool allowDeveloperExceptionPage )
325
386
{
326
387
Debug . Assert ( _builtApplication is not null ) ;
327
388
@@ -332,7 +393,7 @@ private void ConfigureApplication(WebHostBuilderContext context, IApplicationBui
332
393
app . Properties . Remove ( EndpointRouteBuilderKey ) ;
333
394
}
334
395
335
- if ( context . HostingEnvironment . IsDevelopment ( ) )
396
+ if ( allowDeveloperExceptionPage && context . HostingEnvironment . IsDevelopment ( ) )
336
397
{
337
398
app . UseDeveloperExceptionPage ( ) ;
338
399
}
0 commit comments