diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs b/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs index 292faa9a9d..c97c7090f2 100644 --- a/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs +++ b/src/Microsoft.AspNet.Mvc.Core/MvcRouteHandler.cs @@ -1,10 +1,7 @@  using System; -using System.Collections.Generic; using System.Diagnostics.Contracts; -using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNet.Abstractions; using Microsoft.AspNet.DependencyInjection; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Routing; @@ -26,85 +23,49 @@ namespace Microsoft.AspNet.Mvc public async Task RouteAsync([NotNull] RouteContext context) { - using (EnsureScopedServiceProvider(context.HttpContext)) + var services = context.HttpContext.RequestServices; + 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 actionSelector = services.GetService(); + var actionDescriptor = await actionSelector.SelectAsync(requestContext); + if (actionDescriptor == null) { - var services = context.HttpContext.RequestServices; - Contract.Assert(services != null); - - var requestContext = new RequestContext(context.HttpContext, context.Values); - - var actionSelector = services.GetService(); - var actionDescriptor = await actionSelector.SelectAsync(requestContext); - if (actionDescriptor == null) - { - return; - } - - var actionContext = new ActionContext(context.HttpContext, context.Router, context.Values, actionDescriptor); - - var contextAccessor = services.GetService>(); - using (contextAccessor.SetContextSource(() => actionContext, PreventExchange)) - { - var invokerFactory = services.GetService(); - var invoker = invokerFactory.CreateInvoker(actionContext); - if (invoker == null) - { - var ex = new InvalidOperationException( - Resources.FormatActionInvokerFactory_CouldNotCreateInvoker(actionDescriptor)); - - // Add tracing/logging (what do we think of this pattern of tacking on extra data on the exception?) - ex.Data.Add("AD", actionDescriptor); - - throw ex; - } - - await invoker.InvokeActionAsync(); - - 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; + return; } - var applicationServices = httpContext.ApplicationServices; + var actionContext = new ActionContext(context.HttpContext, context.Router, context.Values, actionDescriptor); - var scopeFactory = applicationServices.GetService(); - var scope = scopeFactory.CreateScope(); + var contextAccessor = services.GetService>(); + using (contextAccessor.SetContextSource(() => actionContext, PreventExchange)) + { + var invokerFactory = services.GetService(); + var invoker = invokerFactory.CreateInvoker(actionContext); + if (invoker == null) + { + var ex = new InvalidOperationException( + Resources.FormatActionInvokerFactory_CouldNotCreateInvoker(actionDescriptor)); - var scopeHolder = new ScopeHolder(httpContext, scope); - httpContext.RequestServices = scope.ServiceProvider; - return scopeHolder; + // Add tracing/logging (what do we think of this pattern of tacking on extra data on the exception?) + ex.Data.Add("AD", actionDescriptor); + + throw ex; + } + + await invoker.InvokeActionAsync(); + + context.IsHandled = true; + } } private ActionContext PreventExchange(ActionContext contex) { 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(); - } - } } }