Cleanup services

Explicitly register nestedprovider managers
Make IActionSelector singleton
This commit is contained in:
Yishai Galatzer 2015-02-19 11:10:45 -08:00
parent cf80721994
commit b12c4c5ef8
5 changed files with 45 additions and 34 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.Collections.Generic;
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.Mvc
{
@ -16,13 +17,17 @@ namespace Microsoft.AspNet.Mvc
/// <param name="action">The <see cref="ActionDescriptor"/> for which constraints are being created.</param>
/// <param name="items">The list of <see cref="ActionConstraintItem"/> objects.</param>
public ActionConstraintProviderContext(
[NotNull] HttpContext context,
[NotNull] ActionDescriptor action,
[NotNull] IList<ActionConstraintItem> items)
{
HttpContext = context;
Action = action;
Results = items;
}
public HttpContext HttpContext { get; }
/// <summary>
/// The <see cref="ActionDescriptor"/> for which constraints are being created.
/// </summary>

View File

@ -16,17 +16,6 @@ namespace Microsoft.AspNet.Mvc
/// </remarks>
public class DefaultActionConstraintProvider : INestedProvider<ActionConstraintProviderContext>
{
private readonly IServiceProvider _services;
/// <summary>
/// Creates a new <see cref="DefaultActionConstraintProvider"/>.
/// </summary>
/// <param name="services">The per-request services.</param>
public DefaultActionConstraintProvider(IServiceProvider services)
{
_services = services;
}
/// <inheritdoc />
public int Order
{
@ -38,13 +27,13 @@ namespace Microsoft.AspNet.Mvc
{
foreach (var item in context.Results)
{
ProvideConstraint(item);
ProvideConstraint(item, context.HttpContext.RequestServices);
}
callNext();
}
private void ProvideConstraint(ActionConstraintItem item)
private void ProvideConstraint(ActionConstraintItem item, IServiceProvider services)
{
// Don't overwrite anything that was done by a previous provider.
if (item.Constraint != null)
@ -62,7 +51,7 @@ namespace Microsoft.AspNet.Mvc
var factory = item.Metadata as IActionConstraintFactory;
if (factory != null)
{
item.Constraint = factory.CreateInstance(_services);
item.Constraint = factory.CreateInstance(services);
return;
}
}

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.Logging;
using Microsoft.AspNet.Mvc.Routing;
@ -43,7 +44,7 @@ namespace Microsoft.AspNet.Mvc
var candidates = new List<ActionSelectorCandidate>();
foreach (var action in matchingRouteConstraints)
{
var constraints = GetConstraints(action);
var constraints = GetConstraints(context.HttpContext, action);
candidates.Add(new ActionSelectorCandidate(action, constraints));
}
@ -253,7 +254,7 @@ namespace Microsoft.AspNet.Mvc
return descriptors.Items;
}
private IReadOnlyList<IActionConstraint> GetConstraints(ActionDescriptor action)
private IReadOnlyList<IActionConstraint> GetConstraints(HttpContext httpContext, ActionDescriptor action)
{
if (action.ActionConstraints == null || action.ActionConstraints.Count == 0)
{
@ -261,7 +262,7 @@ namespace Microsoft.AspNet.Mvc
}
var items = action.ActionConstraints.Select(c => new ActionConstraintItem(c)).ToList();
var context = new ActionConstraintProviderContext(action, items);
var context = new ActionConstraintProviderContext(httpContext, action, items);
_actionConstraintProvider.Invoke(context);

View File

@ -23,22 +23,24 @@ namespace Microsoft.AspNet.Mvc
{
public class MvcServices
{
public static IEnumerable<IServiceDescriptor> GetDefaultServices(IConfiguration configuration = null)
public static IEnumerable<IServiceDescriptor> GetDefaultServices()
{
return GetDefaultServices(null);
}
public static IEnumerable<IServiceDescriptor> GetDefaultServices(IConfiguration configuration)
{
var describe = new ServiceDescriber(configuration);
// Options and core services.
yield return describe.Transient<IConfigureOptions<MvcOptions>, MvcOptionsSetup>();
yield return describe.Transient<IConfigureOptions<RazorViewEngineOptions>, RazorViewEngineOptionsSetup>();
yield return describe.Transient<IAssemblyProvider, DefaultAssemblyProvider>();
yield return describe.Transient(typeof(INestedProviderManager<>), typeof(NestedProviderManager<>));
yield return describe.Transient(
typeof(INestedProviderManagerAsync<>),
typeof(NestedProviderManagerAsync<>));
yield return describe.Transient<MvcMarkerService, MvcMarkerService>();
yield return describe.Singleton(typeof(ITypeActivatorCache), typeof(DefaultTypeActivatorCache));
yield return describe.Scoped(typeof(IScopedInstance<>), typeof(ScopedInstance<>));
// Core action discovery, filters and action execution.
// These are consumed only when creating action descriptors, then they can be de-allocated
@ -56,25 +58,34 @@ namespace Microsoft.AspNet.Mvc
// This provider needs access to the per-request services, but might be used many times for a given
// request.
yield return describe.Scoped<INestedProvider<ActionConstraintProviderContext>,
yield return describe.Transient<INestedProviderManager<ActionConstraintProviderContext>,
NestedProviderManager<ActionConstraintProviderContext>>();
yield return describe.Transient<INestedProvider<ActionConstraintProviderContext>,
DefaultActionConstraintProvider>();
yield return describe.Singleton<IActionSelectorDecisionTreeProvider, ActionSelectorDecisionTreeProvider>();
yield return describe.Scoped<IActionSelector, DefaultActionSelector>();
yield return describe.Singleton<IActionSelector, DefaultActionSelector>();
yield return describe.Transient<IControllerActionArgumentBinder, DefaultControllerActionArgumentBinder>();
yield return describe.Transient<IObjectModelValidator, DefaultObjectValidator>();
yield return describe.Transient<INestedProviderManager<ActionDescriptorProviderContext>,
NestedProviderManager<ActionDescriptorProviderContext>>();
yield return describe.Transient<INestedProvider<ActionDescriptorProviderContext>,
ControllerActionDescriptorProvider>();
yield return describe.Transient<INestedProviderManager<ActionInvokerProviderContext>,
NestedProviderManager<ActionInvokerProviderContext>>();
yield return describe.Transient<INestedProvider<ActionInvokerProviderContext>,
ControllerActionInvokerProvider>();
yield return describe.Singleton<IActionDescriptorsCollectionProvider,
DefaultActionDescriptorsCollectionProvider>();
// The IGlobalFilterProvider is used to build the action descriptors (likely once) and so should
// remain transient to avoid keeping it in memory.
yield return describe.Transient<IGlobalFilterProvider, DefaultGlobalFilterProvider>();
yield return describe.Transient<INestedProviderManager<FilterProviderContext>,
NestedProviderManager<FilterProviderContext>>();
yield return describe.Transient<INestedProvider<FilterProviderContext>, DefaultFilterProvider>();
yield return describe.Transient<FormatFilter, FormatFilter>();
@ -89,7 +100,7 @@ namespace Microsoft.AspNet.Mvc
yield return describe.Transient<IModelBinderProvider, DefaultModelBindersProvider>();
yield return describe.Transient<IValueProviderFactoryProvider, DefaultValueProviderFactoryProvider>();
yield return describe.Transient<IOutputFormattersProvider, DefaultOutputFormattersProvider>();
yield return describe.Instance<JsonOutputFormatter>(new JsonOutputFormatter());
yield return describe.Instance(new JsonOutputFormatter());
yield return describe.Transient<IModelValidatorProviderProvider, DefaultModelValidatorProviderProvider>();
yield return describe.Transient<IValidationExcludeFiltersProvider,
@ -130,11 +141,11 @@ namespace Microsoft.AspNet.Mvc
yield return describe.Scoped<IViewStartProvider, ViewStartProvider>();
yield return describe.Transient<IRazorViewFactory, RazorViewFactory>();
yield return describe.Singleton<IRazorPageActivator, RazorPageActivator>();
// Virtual path view factory needs to stay scoped so views can get get scoped services.
yield return describe.Scoped<IRazorPageFactory, VirtualPathRazorPageFactory>();
// View and rendering helpers
yield return describe.Transient<IHtmlHelper, HtmlHelper>();
yield return describe.Transient(typeof(IHtmlHelper<>), typeof(HtmlHelper<>));
yield return describe.Scoped<IUrlHelper, UrlHelper>();
@ -152,19 +163,21 @@ namespace Microsoft.AspNet.Mvc
yield return describe.Transient<IViewComponentSelector, DefaultViewComponentSelector>();
yield return describe.Singleton<IViewComponentActivator, DefaultViewComponentActivator>();
yield return describe.Transient<IViewComponentInvokerFactory, DefaultViewComponentInvokerFactory>();
yield return describe.Transient<INestedProviderManager<ViewComponentInvokerProviderContext>,
NestedProviderManager<ViewComponentInvokerProviderContext>>();
yield return describe.Transient<INestedProvider<ViewComponentInvokerProviderContext>,
DefaultViewComponentInvokerProvider>();
yield return describe.Transient<IViewComponentHelper, DefaultViewComponentHelper>();
// Security and Authorization
yield return describe.Singleton<IClaimUidExtractor, DefaultClaimUidExtractor>();
yield return describe.Singleton<AntiForgery, AntiForgery>();
yield return describe.Singleton<IAntiForgeryAdditionalDataProvider,
DefaultAntiForgeryAdditionalDataProvider>();
// Api Description
yield return describe.Transient<INestedProviderManager<ApiDescriptionProviderContext>,
NestedProviderManager<ApiDescriptionProviderContext>>();
yield return describe.Singleton<IApiDescriptionGroupCollectionProvider,
ApiDescriptionGroupCollectionProvider>();
yield return describe.Transient<INestedProvider<ApiDescriptionProviderContext>,

View File

@ -745,7 +745,7 @@ namespace Microsoft.AspNet.Mvc
var actionConstraintProvider = new NestedProviderManager<ActionConstraintProviderContext>(
new INestedProvider<ActionConstraintProviderContext>[]
{
new DefaultActionConstraintProvider(serviceContainer),
new DefaultActionConstraintProvider(),
});
var defaultActionSelector = new DefaultActionSelector(
@ -831,7 +831,7 @@ namespace Microsoft.AspNet.Mvc
var actionConstraintProvider = new NestedProviderManager<ActionConstraintProviderContext>(
new INestedProvider<ActionConstraintProviderContext>[]
{
new DefaultActionConstraintProvider(new ServiceContainer()),
new DefaultActionConstraintProvider(),
new BooleanConstraintProvider(),
});
@ -860,14 +860,17 @@ namespace Microsoft.AspNet.Mvc
var routeData = new RouteData();
routeData.Routers.Add(new Mock<IRouter>(MockBehavior.Strict).Object);
var serviceContainer = new ServiceContainer();
var httpContext = new Mock<HttpContext>(MockBehavior.Strict);
var request = new Mock<HttpRequest>(MockBehavior.Strict);
httpContext.SetupGet(c => c.Request).Returns(request.Object);
request.SetupGet(r => r.Method).Returns(httpMethod);
request.SetupGet(r => r.Path).Returns(new PathString());
httpContext.SetupGet(c => c.Request).Returns(request.Object);
httpContext.SetupGet(c => c.RequestServices).Returns(serviceContainer);
return new RouteContext(httpContext.Object)
{
RouteData = routeData,