2
2
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3
3
4
4
using System ;
5
+ using System . Diagnostics ;
5
6
using System . Threading . Tasks ;
6
7
using Microsoft . AspNetCore . Http ;
7
8
using Microsoft . AspNetCore . Http . Features ;
@@ -12,7 +13,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
12
13
public class RequestServicesContainerMiddleware
13
14
{
14
15
private readonly RequestDelegate _next ;
15
- private IServiceScopeFactory _scopeFactory ;
16
+ private readonly IServiceScopeFactory _scopeFactory ;
16
17
17
18
public RequestServicesContainerMiddleware ( RequestDelegate next , IServiceScopeFactory scopeFactory )
18
19
{
@@ -25,37 +26,37 @@ public RequestServicesContainerMiddleware(RequestDelegate next, IServiceScopeFac
25
26
throw new ArgumentNullException ( nameof ( scopeFactory ) ) ;
26
27
}
27
28
28
- _scopeFactory = scopeFactory ;
29
29
_next = next ;
30
+ _scopeFactory = scopeFactory ;
30
31
}
31
32
32
33
public async Task Invoke ( HttpContext httpContext )
33
34
{
34
- if ( httpContext == null )
35
- {
36
- throw new ArgumentNullException ( nameof ( httpContext ) ) ;
37
- }
35
+ Debug . Assert ( httpContext != null ) ;
38
36
39
- var existingFeature = httpContext . Features . Get < IServiceProvidersFeature > ( ) ;
37
+ // local cache for virtual disptach result
38
+ var features = httpContext . Features ;
39
+ var existingFeature = features . Get < IServiceProvidersFeature > ( ) ;
40
40
41
- // All done if request services is set
41
+ // All done if RequestServices is set
42
42
if ( existingFeature ? . RequestServices != null )
43
43
{
44
44
await _next . Invoke ( httpContext ) ;
45
45
return ;
46
46
}
47
47
48
- using ( var feature = new RequestServicesFeature ( _scopeFactory ) )
48
+ var replacementFeature = new RequestServicesFeature ( _scopeFactory ) ;
49
+
50
+ try
51
+ {
52
+ features . Set < IServiceProvidersFeature > ( replacementFeature ) ;
53
+ await _next . Invoke ( httpContext ) ;
54
+ }
55
+ finally
49
56
{
50
- try
51
- {
52
- httpContext . Features . Set < IServiceProvidersFeature > ( feature ) ;
53
- await _next . Invoke ( httpContext ) ;
54
- }
55
- finally
56
- {
57
- httpContext . Features . Set ( existingFeature ) ;
58
- }
57
+ replacementFeature . Dispose ( ) ;
58
+ // Restore previous feature state
59
+ features . Set ( existingFeature ) ;
59
60
}
60
61
}
61
62
}
0 commit comments