Skip to content

Commit 2697ad9

Browse files
benaadamsdavidfowl
authored andcommitted
Faster RequestServices (aspnet#941)
* Faster RequestServices
1 parent 1b01da7 commit 2697ad9

File tree

2 files changed

+22
-24
lines changed

2 files changed

+22
-24
lines changed

src/Microsoft.AspNetCore.Hosting/Internal/RequestServicesContainerMiddleware.cs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Diagnostics;
56
using System.Threading.Tasks;
67
using Microsoft.AspNetCore.Http;
78
using Microsoft.AspNetCore.Http.Features;
@@ -12,7 +13,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
1213
public class RequestServicesContainerMiddleware
1314
{
1415
private readonly RequestDelegate _next;
15-
private IServiceScopeFactory _scopeFactory;
16+
private readonly IServiceScopeFactory _scopeFactory;
1617

1718
public RequestServicesContainerMiddleware(RequestDelegate next, IServiceScopeFactory scopeFactory)
1819
{
@@ -25,37 +26,37 @@ public RequestServicesContainerMiddleware(RequestDelegate next, IServiceScopeFac
2526
throw new ArgumentNullException(nameof(scopeFactory));
2627
}
2728

28-
_scopeFactory = scopeFactory;
2929
_next = next;
30+
_scopeFactory = scopeFactory;
3031
}
3132

3233
public async Task Invoke(HttpContext httpContext)
3334
{
34-
if (httpContext == null)
35-
{
36-
throw new ArgumentNullException(nameof(httpContext));
37-
}
35+
Debug.Assert(httpContext != null);
3836

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>();
4040

41-
// All done if request services is set
41+
// All done if RequestServices is set
4242
if (existingFeature?.RequestServices != null)
4343
{
4444
await _next.Invoke(httpContext);
4545
return;
4646
}
4747

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
4956
{
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);
5960
}
6061
}
6162
}

src/Microsoft.AspNetCore.Hosting/Internal/RequestServicesFeature.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,22 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Diagnostics;
56
using Microsoft.AspNetCore.Http.Features;
67
using Microsoft.Extensions.DependencyInjection;
78

89
namespace Microsoft.AspNetCore.Hosting.Internal
910
{
1011
public class RequestServicesFeature : IServiceProvidersFeature, IDisposable
1112
{
12-
private IServiceScopeFactory _scopeFactory;
13+
private readonly IServiceScopeFactory _scopeFactory;
1314
private IServiceProvider _requestServices;
1415
private IServiceScope _scope;
1516
private bool _requestServicesSet;
1617

1718
public RequestServicesFeature(IServiceScopeFactory scopeFactory)
1819
{
19-
if (scopeFactory == null)
20-
{
21-
throw new ArgumentNullException(nameof(scopeFactory));
22-
}
23-
20+
Debug.Assert(scopeFactory != null);
2421
_scopeFactory = scopeFactory;
2522
}
2623

0 commit comments

Comments
 (0)