6
6
using System . Diagnostics ;
7
7
using System . Linq ;
8
8
using System . Reflection ;
9
+ using System . Runtime . ExceptionServices ;
9
10
using System . Runtime . InteropServices ;
10
11
using System . Threading ;
11
12
using System . Threading . Tasks ;
@@ -38,7 +39,7 @@ internal class WebHost : IWebHost
38
39
private readonly AggregateException _hostingStartupErrors ;
39
40
40
41
private IServiceProvider _applicationServices ;
41
- private RequestDelegate _application ;
42
+ private ExceptionDispatchInfo _applicationServicesException ;
42
43
private ILogger < WebHost > _logger ;
43
44
44
45
private bool _stopped ;
@@ -88,7 +89,6 @@ public IServiceProvider Services
88
89
{
89
90
get
90
91
{
91
- EnsureApplicationServices ( ) ;
92
92
return _applicationServices ;
93
93
}
94
94
}
@@ -97,15 +97,32 @@ public IFeatureCollection ServerFeatures
97
97
{
98
98
get
99
99
{
100
+ EnsureServer ( ) ;
100
101
return Server ? . Features ;
101
102
}
102
103
}
103
104
105
+ // Called immediately after the constructor so the properties can rely on it.
104
106
public void Initialize ( )
105
107
{
106
- if ( _application == null )
108
+ try
107
109
{
108
- _application = BuildApplication ( ) ;
110
+ EnsureApplicationServices ( ) ;
111
+ }
112
+ catch ( Exception ex )
113
+ {
114
+ // EnsureApplicationServices may have failed due to a missing or throwing Startup class.
115
+ if ( _applicationServices == null )
116
+ {
117
+ _applicationServices = _applicationServiceCollection . BuildServiceProvider ( ) ;
118
+ }
119
+
120
+ if ( ! _options . CaptureStartupErrors )
121
+ {
122
+ throw ;
123
+ }
124
+
125
+ _applicationServicesException = ExceptionDispatchInfo . Capture ( ex ) ;
109
126
}
110
127
}
111
128
@@ -120,13 +137,13 @@ public virtual async Task StartAsync(CancellationToken cancellationToken = defau
120
137
_logger = _applicationServices . GetRequiredService < ILogger < WebHost > > ( ) ;
121
138
_logger . Starting ( ) ;
122
139
123
- Initialize ( ) ;
140
+ var application = BuildApplication ( ) ;
124
141
125
142
_applicationLifetime = _applicationServices . GetRequiredService < IApplicationLifetime > ( ) as ApplicationLifetime ;
126
143
_hostedServiceExecutor = _applicationServices . GetRequiredService < HostedServiceExecutor > ( ) ;
127
144
var diagnosticSource = _applicationServices . GetRequiredService < DiagnosticListener > ( ) ;
128
145
var httpContextFactory = _applicationServices . GetRequiredService < IHttpContextFactory > ( ) ;
129
- var hostingApp = new HostingApplication ( _application , _logger , diagnosticSource , httpContextFactory ) ;
146
+ var hostingApp = new HostingApplication ( application , _logger , diagnosticSource , httpContextFactory ) ;
130
147
await Server . StartAsync ( hostingApp , cancellationToken ) . ConfigureAwait ( false ) ;
131
148
132
149
// Fire IApplicationLifetime.Started
@@ -183,7 +200,7 @@ private RequestDelegate BuildApplication()
183
200
{
184
201
try
185
202
{
186
- EnsureApplicationServices ( ) ;
203
+ _applicationServicesException ? . Throw ( ) ;
187
204
EnsureServer ( ) ;
188
205
189
206
var builderFactory = _applicationServices . GetRequiredService < IApplicationBuilderFactory > ( ) ;
@@ -203,12 +220,6 @@ private RequestDelegate BuildApplication()
203
220
}
204
221
catch ( Exception ex )
205
222
{
206
- // EnsureApplicationServices may have failed due to a missing or throwing Startup class.
207
- if ( _applicationServices == null )
208
- {
209
- _applicationServices = _applicationServiceCollection . BuildServiceProvider ( ) ;
210
- }
211
-
212
223
if ( ! _options . SuppressStatusMessages )
213
224
{
214
225
// Write errors to standard out so they can be retrieved when not in development mode.
0 commit comments