Issue #39 move init code into controller factory

This commit is contained in:
Ryan Nowak 2014-03-06 12:44:36 -08:00
parent 9d0cea17dd
commit 318c19b2f9
3 changed files with 43 additions and 50 deletions

View File

@ -1,7 +1,9 @@
using System;
using System.Linq;
using System.Reflection;
using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.DependencyInjection;
using Microsoft.AspNet.Mvc.ModelBinding;
namespace Microsoft.AspNet.Mvc
{
@ -14,26 +16,20 @@ namespace Microsoft.AspNet.Mvc
_serviceProvider = serviceProvider;
}
public object CreateController(HttpContext context, ActionDescriptor actionDescriptor)
public object CreateController(ActionContext actionContext, ModelStateDictionary modelState)
{
var typedAd = actionDescriptor as ReflectedActionDescriptor;
if (typedAd == null)
var actionDescriptor = actionContext.ActionDescriptor as ReflectedActionDescriptor;
if (actionDescriptor == null)
{
return null;
}
try
{
var controller = ActivatorUtilities.CreateInstance(_serviceProvider, typedAd.ControllerDescriptor.ControllerTypeInfo.AsType());
var controller = ActivatorUtilities.CreateInstance(_serviceProvider, actionDescriptor.ControllerDescriptor.ControllerTypeInfo.AsType());
// TODO: How do we feed the controller with context (need DI improvements)
var contextProperty = controller.GetType().GetRuntimeProperty("Context");
if (contextProperty != null)
{
contextProperty.SetMethod.Invoke(controller, new object[] { context });
}
InitializeController(controller, actionContext, modelState);
return controller;
}
@ -47,5 +43,35 @@ namespace Microsoft.AspNet.Mvc
public void ReleaseController(object controller)
{
}
private void InitializeController(object controller, ActionContext actionContext, ModelStateDictionary modelState)
{
var controllerType = controller.GetType();
foreach (var prop in controllerType.GetRuntimeProperties())
{
if (prop.Name == "Context" && prop.PropertyType == typeof(HttpContext))
{
prop.SetValue(controller, actionContext.HttpContext);
}
else if (prop.Name == "ModelState" && prop.PropertyType == typeof(ModelStateDictionary))
{
prop.SetValue(controller, modelState);
}
}
var method = controllerType.GetRuntimeMethods().FirstOrDefault(m => m.Name.Equals("Initialize", StringComparison.OrdinalIgnoreCase));
if (method == null)
{
return;
}
var args = method.GetParameters()
.Select(p => _serviceProvider.GetService(p.ParameterType)).ToArray();
method.Invoke(controller, args);
}
}
}

View File

@ -1,10 +1,11 @@
using Microsoft.AspNet.Abstractions;

using Microsoft.AspNet.Mvc.ModelBinding;
namespace Microsoft.AspNet.Mvc
{
public interface IControllerFactory
{
object CreateController(HttpContext context, ActionDescriptor actionDescriptor);
object CreateController(ActionContext actionContext, ModelStateDictionary modelState);
void ReleaseController(object controller);
}

View File

@ -35,9 +35,10 @@ namespace Microsoft.AspNet.Mvc
public async Task InvokeActionAsync()
{
IActionResult actionResult = null;
IActionResult actionResult;
object controller = _controllerFactory.CreateController(_actionContext.HttpContext, _descriptor);
var modelState = new ModelStateDictionary();
object controller = _controllerFactory.CreateController(_actionContext, modelState);
if (controller == null)
{
@ -45,9 +46,6 @@ namespace Microsoft.AspNet.Mvc
}
else
{
var modelState = new ModelStateDictionary();
InitializeController(controller, modelState);
var method = _descriptor.MethodInfo;
if (method == null)
@ -68,38 +66,6 @@ namespace Microsoft.AspNet.Mvc
await actionResult.ExecuteResultAsync(_actionContext);
}
private void InitializeController(object controller, ModelStateDictionary modelState)
{
var controllerType = controller.GetType();
foreach (var prop in controllerType.GetRuntimeProperties())
{
if (prop.Name == "Context")
{
if (prop.PropertyType == typeof(HttpContext))
{
prop.SetValue(controller, _actionContext.HttpContext);
}
}
else if (prop.Name == "ModelState" && prop.PropertyType == typeof(ModelStateDictionary))
{
prop.SetValue(controller, modelState);
}
}
var method = controllerType.GetRuntimeMethods().FirstOrDefault(m => m.Name.Equals("Initialize", StringComparison.OrdinalIgnoreCase));
if (method == null)
{
return;
}
var args = method.GetParameters()
.Select(p => _serviceProvider.GetService(p.ParameterType)).ToArray();
method.Invoke(controller, args);
}
private async Task<IDictionary<string, object>> GetParameterValues(ModelStateDictionary modelState)
{
var actionBindingContext = await _bindingProvider.GetActionBindingContextAsync(_actionContext);