让AsyncController与Ninject一起使用

amb*_*g36 5 asp.net-mvc asynchronous ninject

我试图将控制器中的某些操作转换为在使用ninject进行依赖项注入的mvc项目中异步运行.我通过继承AsyncController并将对应于'X'操作的方法更改为'XAsync'和'XCompleted'来执行这些步骤,但异步操作未得到解决.我相信这个问题与ninject有关.我试图将ninject的Controller Action Invoker明确设置为'AsyncControllerActionInvoker':

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

但没有运气.有没有人设法让异步操作与ninject一起使用?

干杯,

amb*_*g36 3

本质上,我面临的问题是 ninject 使用的默认操作调用程序不支持异步操作,当您尝试在控制器中设置操作调用程序时,默认的 ninjectControllerFactory 会覆盖它。我采取了以下步骤来解决该问题:

1.在注入映射中我添加了以下关联:

Bind<IActionInvoker>().To<AsyncControllerActionInvoker>().InSingletonScope();
Run Code Online (Sandbox Code Playgroud)

2.我创建了一个自定义控制器工厂,它基本上是 ninject 的控制器工厂,唯一的区别是它不会覆盖操作调用程序。

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);
    }

}
Run Code Online (Sandbox Code Playgroud)

3.在 OnApplicationStarted() 方法中,我将控制器工厂设置为我的自定义工厂:

ControllerBuilder.Current.SetControllerFactory(new customNinjectControllerFactory(Kernel));`
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。