Получение AsyncController для работы с Ninject - PullRequest
5 голосов
/ 30 августа 2010

Я пытаюсь преобразовать некоторые действия в контроллере для асинхронного запуска в проекте MVC, который использует ninject для внедрения зависимостей. Я выполняю шаги, наследуя AsyncController и меняя методы, соответствующие действию «X», на «XAsync» и «XCompleted», но асинхронное действие не разрешается. Я уверен, что проблема имеет отношение к ninject. Я попытался явно установить для Invino Controller Action Invoker значение «AsyncControllerActionInvoker»:

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

но не повезло. Кому-нибудь удалось заставить действия Async работать с ninject?

ура

Ответы [ 2 ]

3 голосов
/ 30 сентября 2010

По существу, проблема, с которой я столкнулся, заключалась в том, что вызывающий действия по умолчанию, который используется ninject, не поддерживает асинхронные действия, а когда вы пытаетесь установить вызывающее действие в контроллере, по умолчанию его перезаписывает ninjectControllerFactory.Чтобы устранить проблему, я предпринял следующие шаги:

1.В сопоставлении инъекций я добавил следующую связь:

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

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

}

3. В методе OnApplicationStarted () я устанавливаю фабрику контроллера на свой собственный:

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

Надеюсь, это поможет.

0 голосов
/ 16 сентября 2010

После долгих поисков, которые я понял в дополнение к этому, каждый контроллер должен быть явно настроен на использование Action Invoker, который поддерживает асинхронные действия.

...