99using Microsoft . AspNetCore . Hosting ;
1010using Microsoft . AspNetCore . Hosting . Server ;
1111using Microsoft . AspNetCore . Hosting . Server . Features ;
12+ using Microsoft . AspNetCore . Http . Features ;
1213using Microsoft . AspNetCore . Server . Kestrel . Core ;
1314using Microsoft . AspNetCore . TestHost ;
1415using Microsoft . Extensions . Configuration ;
@@ -196,6 +197,32 @@ public void UseKestrel(Action<KestrelServerOptions> configureKestrelOptions)
196197 }
197198
198199 private IWebHost CreateKestrelServer ( IWebHostBuilder builder )
200+ {
201+ ConfigureBuilderToUseKestrel ( builder ) ;
202+
203+ var host = builder . Build ( ) ;
204+
205+ TryConfigureServerPort ( ( ) => GetServerAddressFeature ( host ) ) ;
206+
207+ host . Start ( ) ;
208+ return host ;
209+ }
210+
211+ private void TryConfigureServerPort ( Func < IServerAddressesFeature ? > serverAddressFeatureAccessor )
212+ {
213+ if ( _kestrelPort . HasValue )
214+ {
215+ var saf = serverAddressFeatureAccessor ( ) ;
216+ if ( saf is not null )
217+ {
218+ saf . Addresses . Clear ( ) ;
219+ saf . Addresses . Add ( $ "http://127.0.0.1:{ _kestrelPort } ") ;
220+ saf . PreferHostingUrls = true ;
221+ }
222+ }
223+ }
224+
225+ private void ConfigureBuilderToUseKestrel ( IWebHostBuilder builder )
199226 {
200227 if ( _configureKestrelOptions is not null )
201228 {
@@ -205,19 +232,6 @@ private IWebHost CreateKestrelServer(IWebHostBuilder builder)
205232 {
206233 builder . UseKestrel ( ) ;
207234 }
208-
209- var host = builder . Build ( ) ;
210-
211- if ( _kestrelPort . HasValue )
212- {
213- var saf = host . Services . GetRequiredService < IServerAddressesFeature > ( ) ;
214- saf . Addresses . Clear ( ) ;
215- saf . Addresses . Add ( $ "http://127.0.0.1:{ _kestrelPort } ") ;
216- saf . PreferHostingUrls = true ;
217- }
218-
219- host . Start ( ) ;
220- return host ;
221235 }
222236
223237 /// <summary>
@@ -226,7 +240,7 @@ private IWebHost CreateKestrelServer(IWebHostBuilder builder)
226240 /// <exception cref="InvalidOperationException">Thrown if the provided <typeparamref name="TEntryPoint"/> type has no factory method.</exception>
227241 public void StartServer ( )
228242 {
229- if ( _server != null || _webHost != null )
243+ if ( _webHost != null || _host != null )
230244 {
231245 return ;
232246 }
@@ -288,13 +302,7 @@ public void StartServer()
288302 {
289303 _webHost = CreateKestrelServer ( builder ) ;
290304
291- var serverAddressFeature = _webHost . ServerFeatures . Get < IServerAddressesFeature > ( ) ;
292- if ( serverAddressFeature ? . Addresses . Count > 0 )
293- {
294- // Store the web host address as it's going to be used every time a client is created to communicate to the server
295- _webHostAddress = new Uri ( serverAddressFeature . Addresses . Last ( ) ) ;
296- ClientOptions . BaseAddress = _webHostAddress ;
297- }
305+ TryExtractHostAddress ( ( ) => GetServerAddressFeature ( _webHost ) ) ;
298306 }
299307 else
300308 {
@@ -303,23 +311,38 @@ public void StartServer()
303311 }
304312 }
305313
314+ private void TryExtractHostAddress ( Func < IServerAddressesFeature ? > serverAddressFeatureAccessor )
315+ {
316+ var serverAddressFeature = serverAddressFeatureAccessor ( ) ;
317+ if ( serverAddressFeature ? . Addresses . Count > 0 )
318+ {
319+ // Store the web host address as it's going to be used every time a client is created to communicate to the server
320+ _webHostAddress = new Uri ( serverAddressFeature . Addresses . Last ( ) ) ;
321+ ClientOptions . BaseAddress = _webHostAddress ;
322+ }
323+ }
324+
306325 private void ConfigureHostBuilder ( IHostBuilder hostBuilder )
307326 {
308327 hostBuilder . ConfigureWebHost ( webHostBuilder =>
309328 {
310329 SetContentRoot ( webHostBuilder ) ;
311330 _configuration ( webHostBuilder ) ;
312- if ( ! _useKestrel )
331+ if ( _useKestrel )
313332 {
314- webHostBuilder . UseTestServer ( ) ;
333+ ConfigureBuilderToUseKestrel ( webHostBuilder ) ;
315334 }
316335 else
317336 {
318- webHostBuilder . UseKestrel ( ) ;
337+ webHostBuilder . UseTestServer ( ) ;
319338 }
320339 } ) ;
321340 _host = CreateHost ( hostBuilder ) ;
322- if ( ! _useKestrel )
341+ if ( _useKestrel )
342+ {
343+ TryExtractHostAddress ( ( ) => GetServerAddressFeature ( _host ) ) ;
344+ }
345+ else
323346 {
324347 _server = ( TestServer ) _host . Services . GetRequiredService < IServer > ( ) ;
325348 }
@@ -549,10 +572,15 @@ private static void EnsureDepsFile()
549572 protected virtual IHost CreateHost ( IHostBuilder builder )
550573 {
551574 var host = builder . Build ( ) ;
575+ TryConfigureServerPort ( ( ) => GetServerAddressFeature ( host ) ) ;
552576 host . Start ( ) ;
553577 return host ;
554578 }
555579
580+ private static IServerAddressesFeature ? GetServerAddressFeature ( IHost host ) => host . Services . GetRequiredService < IServer > ( ) . Features . Get < IServerAddressesFeature > ( ) ;
581+
582+ private static IServerAddressesFeature ? GetServerAddressFeature ( IWebHost webHost ) => webHost . ServerFeatures . Get < IServerAddressesFeature > ( ) ;
583+
556584 /// <summary>
557585 /// Gives a fixture an opportunity to configure the application before it gets built.
558586 /// </summary>
@@ -662,7 +690,7 @@ protected virtual void ConfigureClient(HttpClient client)
662690
663691 if ( _useKestrel )
664692 {
665- if ( _webHost is null )
693+ if ( _webHost is null && _host is null )
666694 {
667695 throw new InvalidOperationException ( Resources . ServerNotInitialized ) ;
668696 }
0 commit comments