Ответ 1
Абсолютно! Вам нужно переопределить DefaultControllerFactory
, чтобы найти настраиваемый контроллер, если он не существует. Затем вам нужно написать IActionInvoker
для обработки имен динамических действий.
Ваш контроллер factory будет выглядеть примерно так:
public class DynamicControllerFactory : DefaultControllerFactory
{
private readonly IServiceLocator _Locator;
public DynamicControllerFactory(IServiceLocator locator)
{
_Locator = locator;
}
protected override Type GetControllerType(string controllerName)
{
var controllerType = base.GetControllerType(controllerName);
// if a controller wasn't found with a matching name, return our dynamic controller
return controllerType ?? typeof (DynamicController);
}
protected override IController GetControllerInstance(Type controllerType)
{
var controller = base.GetControllerInstance(controllerType) as Controller;
var actionInvoker = _Locator.GetInstance<IActionInvoker>();
if (actionInvoker != null)
{
controller.ActionInvoker = actionInvoker;
}
return controller;
}
}
Тогда ваш action invoker будет выглядеть следующим образом:
public class DynamicActionInvoker : ControllerActionInvoker
{
private readonly IServiceLocator _Locator;
public DynamicActionInvoker(IServiceLocator locator)
{
_Locator = locator;
}
protected override ActionDescriptor FindAction(ControllerContext controllerContext,
ControllerDescriptor controllerDescriptor, string actionName)
{
// try to match an existing action name first
var action = base.FindAction(controllerContext, controllerDescriptor, actionName);
if (action != null)
{
return action;
}
// @ray247 The remainder of this you'd probably write on your own...
var actionFinders = _Locator.GetAllInstances<IFindAction>();
if (actionFinders == null)
{
return null;
}
return actionFinders
.Select(f => f.FindAction(controllerContext, controllerDescriptor, actionName))
.Where(d => d != null)
.FirstOrDefault();
}
}
Вы можете увидеть намного больше этого кода здесь. Это старая первая попытка проекта сама по себе и коллега при написании полностью динамического трубопровода MVC. Вы можете использовать его как ссылку и скопировать то, что хотите.
Edit
Я подумал, что я должен добавить некоторые сведения о том, что делает этот код. Мы пытались динамически строить слой MVC вокруг модели домена. Поэтому, если ваш домен содержит класс Product, вы можете перейти к products\alls
, чтобы просмотреть список всех продуктов. Если вы хотите добавить продукт, перейдите к product\add
. Вы можете перейти к product\edit\1
для редактирования продукта. Мы даже пробовали такие вещи, как позволить вам редактировать свойства объекта. Таким образом, product\editprice\1?value=42
установит свойство цены продукта с №1 до 42. (Мои пути могут быть немного неактивными, я больше не могу вспомнить точный синтаксис.) Надеюсь, что это поможет!