¡Absolutamente! Tendrá que anular DefaultControllerFactory
para encontrar un controlador personalizado si no existe uno. Luego deberá escribir un IActionInvoker
para manejar nombres de acciones dinámicas.
Su fábrica de controlador será algo como:
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;
}
}
Luego, su invocador acción sería como:
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();
}
}
Puede ver mucho más de este código here. Es un viejo intento de borrador primero por mí y un compañero de trabajo en la escritura de una tubería de MVC completamente dinámica. Eres libre de usarlo como referencia y copiar lo que quieras.
Editar
que pensé que debería incluir algunos antecedentes sobre lo que hace que el código. Intentamos construir dinámicamente la capa MVC alrededor de un modelo de dominio. Entonces, si su dominio contiene una clase de Producto, puede navegar al products\alls
para ver una lista de todos los productos. Si quisiera agregar un producto, navegaría al product\add
. Puede ir al product\edit\1
para editar un producto. Incluso probamos cosas como permitirle editar propiedades en una entidad. Por lo tanto, product\editprice\1?value=42
establecería la propiedad de precio del producto n. ° 1 a 42. (Es posible que mis rutas estén un poco desajustadas, ya no puedo recordar la sintaxis exacta). ¡Espero que esto ayude!
Hola @Ryan. He intentado implementar DynamicControllerFactory y DynamicActionInvoker desde https://github.com/ryanohs/DynamicServices. Durante el tiempo de ejecución me pidieron el constructor predeterminado de DynamicControllerFactory 1st. Luego agregué uno con implementación vacía. Pero el constructor de parametrización nunca se invoca y el valor _locater nunca se establece. Por lo tanto, al invocar GetControllerInstance, actionInvoker no se configura debido a un _locator nulo. donde he hecho mal¿Necesito dar el valor predeterminado para _locator, o está configurado durante el tiempo de ejecución desde otro lugar? – mesimplybj
¿alguien puede elaborar el escenario cuando se requiera un controlador dinámico y un invocador de acción dinámica? – Thomas