Faster RequestServices (#941)

* Faster RequestServices
This commit is contained in:
Ben Adams 2017-02-14 16:37:38 +00:00 committed by David Fowler
parent 1b01da7a05
commit 2697ad9a37
2 changed files with 22 additions and 24 deletions

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
@ -12,7 +13,7 @@ namespace Microsoft.AspNetCore.Hosting.Internal
public class RequestServicesContainerMiddleware
{
private readonly RequestDelegate _next;
private IServiceScopeFactory _scopeFactory;
private readonly IServiceScopeFactory _scopeFactory;
public RequestServicesContainerMiddleware(RequestDelegate next, IServiceScopeFactory scopeFactory)
{
@ -25,37 +26,37 @@ namespace Microsoft.AspNetCore.Hosting.Internal
throw new ArgumentNullException(nameof(scopeFactory));
}
_scopeFactory = scopeFactory;
_next = next;
_scopeFactory = scopeFactory;
}
public async Task Invoke(HttpContext httpContext)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
Debug.Assert(httpContext != null);
var existingFeature = httpContext.Features.Get<IServiceProvidersFeature>();
// local cache for virtual disptach result
var features = httpContext.Features;
var existingFeature = features.Get<IServiceProvidersFeature>();
// All done if request services is set
// All done if RequestServices is set
if (existingFeature?.RequestServices != null)
{
await _next.Invoke(httpContext);
return;
}
using (var feature = new RequestServicesFeature(_scopeFactory))
var replacementFeature = new RequestServicesFeature(_scopeFactory);
try
{
try
{
httpContext.Features.Set<IServiceProvidersFeature>(feature);
await _next.Invoke(httpContext);
}
finally
{
httpContext.Features.Set(existingFeature);
}
features.Set<IServiceProvidersFeature>(replacementFeature);
await _next.Invoke(httpContext);
}
finally
{
replacementFeature.Dispose();
// Restore previous feature state
features.Set(existingFeature);
}
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
@ -9,18 +10,14 @@ namespace Microsoft.AspNetCore.Hosting.Internal
{
public class RequestServicesFeature : IServiceProvidersFeature, IDisposable
{
private IServiceScopeFactory _scopeFactory;
private readonly IServiceScopeFactory _scopeFactory;
private IServiceProvider _requestServices;
private IServiceScope _scope;
private bool _requestServicesSet;
public RequestServicesFeature(IServiceScopeFactory scopeFactory)
{
if (scopeFactory == null)
{
throw new ArgumentNullException(nameof(scopeFactory));
}
Debug.Assert(scopeFactory != null);
_scopeFactory = scopeFactory;
}