Removed MVC's custom request scope

We need to figure out a consistent way to throw errors when there isn't
a request scope already setup.
This commit is contained in:
David Fowler 2014-04-17 20:10:07 -07:00
parent b3d851dfe9
commit c4f01b8ec9
1 changed files with 33 additions and 72 deletions

View File

@ -1,10 +1,7 @@
 
using System; using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts; using System.Diagnostics.Contracts;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.DependencyInjection; using Microsoft.AspNet.DependencyInjection;
using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Routing; using Microsoft.AspNet.Routing;
@ -25,12 +22,14 @@ namespace Microsoft.AspNet.Mvc
} }
public async Task RouteAsync([NotNull] RouteContext context) public async Task RouteAsync([NotNull] RouteContext context)
{
using (EnsureScopedServiceProvider(context.HttpContext))
{ {
var services = context.HttpContext.RequestServices; var services = context.HttpContext.RequestServices;
Contract.Assert(services != null); Contract.Assert(services != null);
// TODO: Throw an error here that's descriptive enough so that
// users understand they should call the per request scoped middleware
// or set HttpContext.Services manually
var requestContext = new RequestContext(context.HttpContext, context.Values); var requestContext = new RequestContext(context.HttpContext, context.Values);
var actionSelector = services.GetService<IActionSelector>(); var actionSelector = services.GetService<IActionSelector>();
@ -63,48 +62,10 @@ namespace Microsoft.AspNet.Mvc
context.IsHandled = true; context.IsHandled = true;
} }
} }
}
private IDisposable EnsureScopedServiceProvider([NotNull] HttpContext httpContext)
{
if (httpContext.RequestServices != null)
{
// There's already a request-scope, we don't need to create one. It's safe to return null
// here, and that makes sure that we don't accidentally dispose the scope.
return null;
}
var applicationServices = httpContext.ApplicationServices;
var scopeFactory = applicationServices.GetService<IServiceScopeFactory>();
var scope = scopeFactory.CreateScope();
var scopeHolder = new ScopeHolder(httpContext, scope);
httpContext.RequestServices = scope.ServiceProvider;
return scopeHolder;
}
private ActionContext PreventExchange(ActionContext contex) private ActionContext PreventExchange(ActionContext contex)
{ {
throw new InvalidOperationException(Resources.ActionContextAccessor_SetValueNotSupported); throw new InvalidOperationException(Resources.ActionContextAccessor_SetValueNotSupported);
} }
private class ScopeHolder : IDisposable
{
private readonly HttpContext _httpContext;
private readonly IServiceScope _scope;
public ScopeHolder([NotNull] HttpContext httpContext, [NotNull] IServiceScope scope)
{
_httpContext = httpContext;
_scope = scope;
}
public void Dispose()
{
_httpContext.RequestServices = null;
_scope.Dispose();
}
}
} }
} }