Use INestedProvider for ADP and AIP

This commit is contained in:
Ryan Nowak 2014-02-26 14:51:19 -08:00
parent d920003194
commit 803f447686
9 changed files with 93 additions and 50 deletions

View File

@ -1,4 +1,5 @@
using Microsoft.AspNet.DependencyInjection; using Microsoft.AspNet.DependencyInjection;
using Microsoft.AspNet.DependencyInjection.NestedProviders;
using Microsoft.AspNet.FileSystems; using Microsoft.AspNet.FileSystems;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.Razor; using Microsoft.AspNet.Mvc.Razor;
@ -19,14 +20,11 @@ namespace Microsoft.AspNet.Mvc.Startup
Add<IActionInvokerFactory, ActionInvokerFactory>(); Add<IActionInvokerFactory, ActionInvokerFactory>();
Add<IActionResultHelper, ActionResultHelper>(); Add<IActionResultHelper, ActionResultHelper>();
Add<IActionResultFactory, ActionResultFactory>(); Add<IActionResultFactory, ActionResultFactory>();
Add<IActionDescriptorProvider, TypeMethodBasedActionDescriptorProvider>();
Add<IParameterDescriptorFactory, DefaultParameterDescriptorFactory>(); Add<IParameterDescriptorFactory, DefaultParameterDescriptorFactory>();
Add<IValueProviderFactory, RouteValueValueProviderFactory>(); Add<IValueProviderFactory, RouteValueValueProviderFactory>();
Add<IValueProviderFactory, QueryStringValueProviderFactory>(); Add<IValueProviderFactory, QueryStringValueProviderFactory>();
Add<IActionInvokerProvider, ActionInvokerProvider>();
Add<IControllerAssemblyProvider, AppDomainControllerAssemblyProvider>(); Add<IControllerAssemblyProvider, AppDomainControllerAssemblyProvider>();
Add<IActionDiscoveryConventions, DefaultActionDiscoveryConventions>(); Add<IActionDiscoveryConventions, DefaultActionDiscoveryConventions>();
AddInstance<IFileSystem>(new PhysicalFileSystem(appRoot)); AddInstance<IFileSystem>(new PhysicalFileSystem(appRoot));
AddInstance<IMvcRazorHost>(new MvcRazorHost(typeof(RazorView).FullName)); AddInstance<IMvcRazorHost>(new MvcRazorHost(typeof(RazorView).FullName));
@ -36,6 +34,12 @@ namespace Microsoft.AspNet.Mvc.Startup
Add<IRazorCompilationService, RazorCompilationService>(); Add<IRazorCompilationService, RazorCompilationService>();
Add<IVirtualPathViewFactory, VirtualPathViewFactory>(); Add<IVirtualPathViewFactory, VirtualPathViewFactory>();
Add<IViewEngine, RazorViewEngine>(); Add<IViewEngine, RazorViewEngine>();
// This is temporary until DI has some magic for it
Add<INestedProviderManager<ActionDescriptorProviderContext>, NestedProviderManager<ActionDescriptorProviderContext>>();
Add<INestedProviderManager<ActionInvokerProviderContext>, NestedProviderManager<ActionInvokerProviderContext>>();
Add<INestedProvider<ActionDescriptorProviderContext>, TypeMethodBasedActionDescriptorProvider>();
Add<INestedProvider<ActionInvokerProviderContext>, ActionInvokerProvider>();
} }
private void Add<T, TU>() where TU : T private void Add<T, TU>() where TU : T

View File

@ -0,0 +1,15 @@

using System.Collections.Generic;
namespace Microsoft.AspNet.Mvc
{
public class ActionDescriptorProviderContext
{
public ActionDescriptorProviderContext()
{
ActionDescriptors = new List<ActionDescriptor>();
}
public List<ActionDescriptor> ActionDescriptors { get; private set; }
}
}

View File

@ -1,23 +1,21 @@
namespace Microsoft.AspNet.Mvc using Microsoft.AspNet.DependencyInjection;
namespace Microsoft.AspNet.Mvc
{ {
public class ActionInvokerFactory : IActionInvokerFactory public class ActionInvokerFactory : IActionInvokerFactory
{ {
private readonly IActionResultFactory _actionResultFactory; private readonly INestedProviderManager<ActionInvokerProviderContext> _actionInvokerProvider;
private readonly IActionInvokerProvider _actionInvokerProvider;
private readonly IActionDescriptorProvider _routeContextProvider;
public ActionInvokerFactory(IActionResultFactory actionResultFactory, public ActionInvokerFactory(INestedProviderManager<ActionInvokerProviderContext> actionInvokerProvider)
IActionDescriptorProvider actionDescriptorProvider,
IActionInvokerProvider actionInvokerProvider)
{ {
_actionResultFactory = actionResultFactory;
_routeContextProvider = actionDescriptorProvider;
_actionInvokerProvider = actionInvokerProvider; _actionInvokerProvider = actionInvokerProvider;
} }
public IActionInvoker CreateInvoker(ActionContext actionContext) public IActionInvoker CreateInvoker(ActionContext actionContext)
{ {
return _actionInvokerProvider.GetInvoker(actionContext); var context = new ActionInvokerProviderContext(actionContext);
_actionInvokerProvider.Invoke(context);
return context.ActionInvoker;
} }
} }
} }

View File

@ -17,21 +17,28 @@ namespace Microsoft.AspNet.Mvc
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
} }
public IActionInvoker GetInvoker(ActionContext actionContext) public int Order
{ {
var ad = actionContext.ActionDescriptor as TypeMethodBasedActionDescriptor; get { return 0; }
}
public void Invoke(ActionInvokerProviderContext context, Action callNext)
{
var ad = context.ActionContext.ActionDescriptor as TypeMethodBasedActionDescriptor;
if (ad != null) if (ad != null)
{ {
return new TypeMethodBasedActionInvoker( context.ActionInvoker = new TypeMethodBasedActionInvoker(
actionContext, context.ActionContext,
ad, ad,
_actionResultFactory, _actionResultFactory,
_controllerFactory, _controllerFactory,
_serviceProvider); _serviceProvider);
} }
return null; callNext();
} }
} }
} }

View File

@ -0,0 +1,21 @@
using System;
namespace Microsoft.AspNet.Mvc
{
public class ActionInvokerProviderContext
{
public ActionInvokerProviderContext(ActionContext actionContext)
{
if (actionContext == null)
{
throw new ArgumentNullException("actionContext");
}
ActionContext = actionContext;
}
public ActionContext ActionContext { get; private set; }
public IActionInvoker ActionInvoker { get; set; }
}
}

View File

@ -2,18 +2,21 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.DependencyInjection;
using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
public class DefaultActionSelector : IActionSelector public class DefaultActionSelector : IActionSelector
{ {
private readonly IEnumerable<IActionDescriptorProvider> _actionDescriptorProviders; private readonly INestedProviderManager<ActionDescriptorProviderContext> _actionDescriptorProvider;
private readonly IEnumerable<IValueProviderFactory> _valueProviderFactory; private readonly IEnumerable<IValueProviderFactory> _valueProviderFactory;
public DefaultActionSelector(IEnumerable<IActionDescriptorProvider> actionDescriptorProviders, IEnumerable<IValueProviderFactory> valueProviderFactories) public DefaultActionSelector(
INestedProviderManager<ActionDescriptorProviderContext> actionDescriptorProvider,
IEnumerable<IValueProviderFactory> valueProviderFactories)
{ {
_actionDescriptorProviders = actionDescriptorProviders; _actionDescriptorProvider = actionDescriptorProvider;
_valueProviderFactory = valueProviderFactories; _valueProviderFactory = valueProviderFactories;
} }
@ -24,7 +27,10 @@ namespace Microsoft.AspNet.Mvc
throw new ArgumentNullException("context"); throw new ArgumentNullException("context");
} }
var allDescriptors = _actionDescriptorProviders.SelectMany(d => d.GetDescriptors()); var actionDescriptorProviderContext = new ActionDescriptorProviderContext();
_actionDescriptorProvider.Invoke(actionDescriptorProviderContext);
var allDescriptors = actionDescriptorProviderContext.Results;
var matching = allDescriptors.Where(ad => Match(ad, context)).ToList(); var matching = allDescriptors.Where(ad => Match(ad, context)).ToList();
if (matching.Count == 0) if (matching.Count == 0)

View File

@ -1,9 +1,9 @@
using System.Collections.Generic; 
using Microsoft.AspNet.DependencyInjection;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
public interface IActionDescriptorProvider public interface IActionDescriptorProvider : INestedProvider<ActionDescriptorProviderContext>
{ {
IEnumerable<ActionDescriptor> GetDescriptors();
} }
} }

View File

@ -1,7 +1,8 @@
namespace Microsoft.AspNet.Mvc using Microsoft.AspNet.DependencyInjection;
namespace Microsoft.AspNet.Mvc
{ {
public interface IActionInvokerProvider public interface IActionInvokerProvider : INestedProvider<ActionInvokerProviderContext>
{ {
IActionInvoker GetInvoker(ActionContext actionContext);
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -22,6 +23,17 @@ namespace Microsoft.AspNet.Mvc
_parameterDescriptorFactory = parameterDescriptorFactory; _parameterDescriptorFactory = parameterDescriptorFactory;
} }
public int Order
{
get { return 0; }
}
public void Invoke(ActionDescriptorProviderContext context, Action callNext)
{
context.ActionDescriptors.AddRange(GetDescriptors());
callNext();
}
public IEnumerable<ActionDescriptor> GetDescriptors() public IEnumerable<ActionDescriptor> GetDescriptors()
{ {
var assemblies = _controllerAssemblyProvider.Assemblies; var assemblies = _controllerAssemblyProvider.Assemblies;
@ -84,26 +96,5 @@ namespace Microsoft.AspNet.Mvc
return ad; return ad;
} }
private static void ApplyRest(TypeMethodBasedActionDescriptor descriptor, IEnumerable<string> httpMethods)
{
descriptor.RouteConstraints.Add(new RouteDataActionConstraint("action", RouteKeyHandling.DenyKey));
}
private static void ApplyRpc(TypeMethodBasedActionDescriptor descriptor, ActionInfo convention)
{
var methods = convention.HttpMethods;
// rest action require specific methods, but RPC actions do not.
if (methods != null)
{
descriptor.MethodConstraints = new List<HttpMethodConstraint>
{
new HttpMethodConstraint(methods)
};
}
}
} }
} }