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 ;
@@ -64,28 +65,15 @@ internal WebApplicationBuilder(WebApplicationOptions options, Action<IHostBuilde
64
65
// Runs inline.
65
66
webHostBuilder . Configure ( ConfigureApplication ) ;
66
67
67
- webHostBuilder . UseSetting ( WebHostDefaults . ApplicationKey , _hostApplicationBuilder . Environment . ApplicationName ?? "" ) ;
68
- webHostBuilder . UseSetting ( WebHostDefaults . PreventHostingStartupKey , Configuration [ WebHostDefaults . PreventHostingStartupKey ] ) ;
69
- webHostBuilder . UseSetting ( WebHostDefaults . HostingStartupAssembliesKey , Configuration [ WebHostDefaults . HostingStartupAssembliesKey ] ) ;
70
- webHostBuilder . UseSetting ( WebHostDefaults . HostingStartupExcludeAssembliesKey , Configuration [ WebHostDefaults . HostingStartupExcludeAssembliesKey ] ) ;
68
+ InitializeWebHostSettings ( webHostBuilder ) ;
71
69
} ,
72
70
options =>
73
71
{
74
72
// We've already applied "ASPNETCORE_" environment variables to hosting config
75
73
options . SuppressEnvironmentConfiguration = true ;
76
74
} ) ;
77
75
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 ) ;
76
+ _genericWebHostServiceDescriptor = InitializeHosting ( bootstrapHostBuilder ) ;
89
77
}
90
78
91
79
internal WebApplicationBuilder ( WebApplicationOptions options , bool slim , Action < IHostBuilder > ? configureDefaults = null )
@@ -138,25 +126,83 @@ internal WebApplicationBuilder(WebApplicationOptions options, bool slim, Action<
138
126
bootstrapHostBuilder . ConfigureSlimWebHost (
139
127
webHostBuilder =>
140
128
{
141
- AspNetCore . WebHost . ConfigureWebDefaultsCore ( webHostBuilder ) ;
129
+ AspNetCore . WebHost . ConfigureWebDefaultsSlim ( webHostBuilder ) ;
142
130
143
131
// Runs inline.
144
132
webHostBuilder . Configure ( ConfigureApplication ) ;
145
133
146
- webHostBuilder . UseSetting ( WebHostDefaults . ApplicationKey , _hostApplicationBuilder . Environment . ApplicationName ?? "" ) ;
147
- webHostBuilder . UseSetting ( WebHostDefaults . PreventHostingStartupKey , Configuration [ WebHostDefaults . PreventHostingStartupKey ] ) ;
148
- webHostBuilder . UseSetting ( WebHostDefaults . HostingStartupAssembliesKey , Configuration [ WebHostDefaults . HostingStartupAssembliesKey ] ) ;
149
- webHostBuilder . UseSetting ( WebHostDefaults . HostingStartupExcludeAssembliesKey , Configuration [ WebHostDefaults . HostingStartupExcludeAssembliesKey ] ) ;
134
+ InitializeWebHostSettings ( webHostBuilder ) ;
150
135
} ,
151
136
options =>
152
137
{
153
138
// We've already applied "ASPNETCORE_" environment variables to hosting config
154
139
options . SuppressEnvironmentConfiguration = true ;
155
140
} ) ;
156
141
142
+ _genericWebHostServiceDescriptor = InitializeHosting ( bootstrapHostBuilder ) ;
143
+ }
144
+
145
+ internal WebApplicationBuilder ( WebApplicationOptions options , bool slim , bool empty , Action < IHostBuilder > ? configureDefaults = null )
146
+ {
147
+ Debug . Assert ( ! slim , "should only be called with slim: false" ) ;
148
+ Debug . Assert ( empty , "should only be called with empty: true" ) ;
149
+
150
+ var configuration = new ConfigurationManager ( ) ;
151
+
152
+ // empty builder should still default the ContentRoot as usual. This is the expected behavior for all WebApplicationBuilders.
153
+ SetDefaultContentRoot ( options , configuration ) ;
154
+
155
+ _hostApplicationBuilder = Microsoft . Extensions . Hosting . Host . CreateEmptyApplicationBuilder ( new HostApplicationBuilderSettings
156
+ {
157
+ Args = options . Args ,
158
+ ApplicationName = options . ApplicationName ,
159
+ EnvironmentName = options . EnvironmentName ,
160
+ ContentRootPath = options . ContentRootPath ,
161
+ Configuration = configuration ,
162
+ } ) ;
163
+
164
+ // Set WebRootPath if necessary
165
+ if ( options . WebRootPath is not null )
166
+ {
167
+ Configuration . AddInMemoryCollection ( new [ ]
168
+ {
169
+ new KeyValuePair < string , string ? > ( WebHostDefaults . WebRootKey , options . WebRootPath ) ,
170
+ } ) ;
171
+ }
172
+
173
+ // Run methods to configure web host defaults early to populate services
174
+ var bootstrapHostBuilder = new BootstrapHostBuilder ( _hostApplicationBuilder ) ;
175
+
176
+ // This is for testing purposes
177
+ configureDefaults ? . Invoke ( bootstrapHostBuilder ) ;
178
+
179
+ bootstrapHostBuilder . ConfigureSlimWebHost (
180
+ webHostBuilder =>
181
+ {
182
+ // Note this doesn't configure any WebHost server - Kestrel or otherwise.
183
+ // It also doesn't register Routing, HostFiltering, or ForwardedHeaders.
184
+ // It is "empty" and up to the caller to configure these services.
185
+
186
+ // Runs inline.
187
+ webHostBuilder . Configure ( ( context , app ) => ConfigureApplication ( context , app , allowDeveloperExceptionPage : false ) ) ;
188
+
189
+ InitializeWebHostSettings ( webHostBuilder ) ;
190
+ } ,
191
+ options =>
192
+ {
193
+ // This is an "empty" builder, so don't add the "ASPNETCORE_" environment variables
194
+ options . SuppressEnvironmentConfiguration = true ;
195
+ } ) ;
196
+
197
+ _genericWebHostServiceDescriptor = InitializeHosting ( bootstrapHostBuilder ) ;
198
+ }
199
+
200
+ [ MemberNotNull ( nameof ( Environment ) , nameof ( Host ) , nameof ( WebHost ) ) ]
201
+ private ServiceDescriptor InitializeHosting ( BootstrapHostBuilder bootstrapHostBuilder )
202
+ {
157
203
// This applies the config from ConfigureWebHostDefaults
158
204
// Grab the GenericWebHostService ServiceDescriptor so we can append it after any user-added IHostedServices during Build();
159
- _genericWebHostServiceDescriptor = bootstrapHostBuilder . RunDefaultCallbacks ( ) ;
205
+ var genericWebHostServiceDescriptor = bootstrapHostBuilder . RunDefaultCallbacks ( ) ;
160
206
161
207
// Grab the WebHostBuilderContext from the property bag to use in the ConfigureWebHostBuilder. Then
162
208
// grab the IWebHostEnvironment from the webHostContext. This also matches the instance in the IServiceCollection.
@@ -165,6 +211,16 @@ internal WebApplicationBuilder(WebApplicationOptions options, bool slim, Action<
165
211
166
212
Host = new ConfigureHostBuilder ( bootstrapHostBuilder . Context , Configuration , Services ) ;
167
213
WebHost = new ConfigureWebHostBuilder ( webHostContext , Configuration , Services ) ;
214
+
215
+ return genericWebHostServiceDescriptor ;
216
+ }
217
+
218
+ private void InitializeWebHostSettings ( IWebHostBuilder webHostBuilder )
219
+ {
220
+ webHostBuilder . UseSetting ( WebHostDefaults . ApplicationKey , _hostApplicationBuilder . Environment . ApplicationName ?? "" ) ;
221
+ webHostBuilder . UseSetting ( WebHostDefaults . PreventHostingStartupKey , Configuration [ WebHostDefaults . PreventHostingStartupKey ] ) ;
222
+ webHostBuilder . UseSetting ( WebHostDefaults . HostingStartupAssembliesKey , Configuration [ WebHostDefaults . HostingStartupAssembliesKey ] ) ;
223
+ webHostBuilder . UseSetting ( WebHostDefaults . HostingStartupExcludeAssembliesKey , Configuration [ WebHostDefaults . HostingStartupExcludeAssembliesKey ] ) ;
168
224
}
169
225
170
226
private static DefaultServiceProviderFactory GetServiceProviderFactory ( HostApplicationBuilder hostApplicationBuilder )
@@ -272,7 +328,7 @@ private static void AddDefaultServicesSlim(ConfigurationManager configuration, I
272
328
/// <summary>
273
329
/// Provides information about the web hosting environment an application is running.
274
330
/// </summary>
275
- public IWebHostEnvironment Environment { get ; }
331
+ public IWebHostEnvironment Environment { get ; private set ; }
276
332
277
333
/// <summary>
278
334
/// A collection of services for the application to compose. This is useful for adding user provided or framework provided services.
@@ -293,13 +349,13 @@ private static void AddDefaultServicesSlim(ConfigurationManager configuration, I
293
349
/// An <see cref="IWebHostBuilder"/> for configuring server specific properties, but not building.
294
350
/// To build after configuration, call <see cref="Build"/>.
295
351
/// </summary>
296
- public ConfigureWebHostBuilder WebHost { get ; }
352
+ public ConfigureWebHostBuilder WebHost { get ; private set ; }
297
353
298
354
/// <summary>
299
355
/// An <see cref="IHostBuilder"/> for configuring host specific properties, but not building.
300
356
/// To build after configuration, call <see cref="Build"/>.
301
357
/// </summary>
302
- public ConfigureHostBuilder Host { get ; }
358
+ public ConfigureHostBuilder Host { get ; private set ; }
303
359
304
360
IDictionary < object , object > IHostApplicationBuilder . Properties => ( ( IHostApplicationBuilder ) _hostApplicationBuilder ) . Properties ;
305
361
@@ -321,7 +377,10 @@ public WebApplication Build()
321
377
return _builtApplication ;
322
378
}
323
379
324
- private void ConfigureApplication ( WebHostBuilderContext context , IApplicationBuilder app )
380
+ private void ConfigureApplication ( WebHostBuilderContext context , IApplicationBuilder app ) =>
381
+ ConfigureApplication ( context , app , allowDeveloperExceptionPage : true ) ;
382
+
383
+ private void ConfigureApplication ( WebHostBuilderContext context , IApplicationBuilder app , bool allowDeveloperExceptionPage )
325
384
{
326
385
Debug . Assert ( _builtApplication is not null ) ;
327
386
@@ -332,7 +391,7 @@ private void ConfigureApplication(WebHostBuilderContext context, IApplicationBui
332
391
app . Properties . Remove ( EndpointRouteBuilderKey ) ;
333
392
}
334
393
335
- if ( context . HostingEnvironment . IsDevelopment ( ) )
394
+ if ( allowDeveloperExceptionPage && context . HostingEnvironment . IsDevelopment ( ) )
336
395
{
337
396
app . UseDeveloperExceptionPage ( ) ;
338
397
}
0 commit comments