2010-08-30 25 views
5

Estoy tratando de convertir algunas acciones dentro de un controlador para que se ejecuten de forma asincrónica en un proyecto de mvc que esté usando ninject para inyección de dependencias. Estoy siguiendo los pasos heredando AsyncController y cambiando los métodos que corresponden a la acción 'X' a 'XAsync' y 'XCompleted', pero la acción asíncrona no se está resolviendo. Estoy seguro de que el problema tiene que ver con ninject. He tratado de establecer explícitamente de ninject Action Controller invocador a 'AsyncControllerActionInvoker':Obtención de AsyncController para trabajar con Ninject

Bind<IActionInvoker>().To<AsyncControllerActionInvoker>().InSingletonScope();

pero no hubo suerte. ¿Alguien ha logrado que las acciones Async funcionen con ninject?

aplausos,

Respuesta

3

Esencialmente el problema que estaba enfrentando era que el invocador de acción predeterminado que es usado por ninject no admite acciones asíncronas y cuando intentas establecer la acción invocador en un controlador, el predeterminado ninjectControllerFactory lo reemplaza. Tomé los siguientes pasos para solucionar el problema:

1.In el mapeo de inyección he añadido la siguiente asociación:

Bind<IActionInvoker>().To<AsyncControllerActionInvoker>().InSingletonScope(); 

2.He creó una fábrica de controlador personalizado que está básicamente de ninject fábrica de controlador con el único la diferencia es que no sobrescribe el invocador de acción. Método

public class CustomNinjectControllerFactory : DefaultControllerFactory { 
    /// <summary> 
    /// Gets the kernel that will be used to create controllers. 
    /// </summary> 
    public IKernel Kernel { get; private set; } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="NinjectControllerFactory"/> class. 
    /// </summary> 
    /// <param name="kernel">The kernel that should be used to create controllers.</param> 
    public CustomNinjectControllerFactory(IKernel kernel) { 
     Kernel = kernel; 
    } 

    /// <summary> 
    /// Gets a controller instance of type controllerType. 
    /// </summary> 
    /// <param name="requestContext">The request context.</param> 
    /// <param name="controllerType">Type of controller to create.</param> 
    /// <returns>The controller instance.</returns> 
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { 
     if (controllerType == null) { 
      // let the base handle 404 errors with proper culture information 
      return base.GetControllerInstance(requestContext, controllerType); 
     } 

     var controller = Kernel.TryGet(controllerType) as IController; 

     if (controller == null) 
      return base.GetControllerInstance(requestContext, controllerType); 

     var standardController = controller as Controller; 

     if (standardController != null && standardController.ActionInvoker == null) 
      standardController.ActionInvoker = CreateActionInvoker(); 

     return controller; 
    } 

    /// <summary> 
    /// Creates the action invoker. 
    /// </summary> 
    /// <returns>The action invoker.</returns> 
    protected virtual NinjectActionInvoker CreateActionInvoker() { 
     return new NinjectActionInvoker(Kernel); 
    } 

} 

3.In OnApplicationStarted() que establece la fábrica de controlador para mi uno personalizado:

ControllerBuilder.Current.SetControllerFactory(new customNinjectControllerFactory(Kernel));` 

Espero que esto ayude.

+0

Acabo de perder todo un día de depuración en esto. Lamentablemente, he encontrado esta pregunta solo cuando descubrí la solución :) – SWeko

0

Después de mucha búsqueda me di cuenta, además de esto, cada controlador debe configurarse explícitamente para utilizar un invocador de acción que apoya acciones asíncronas.

Cuestiones relacionadas