Ninject в вызываемый класс Webactivator

Я использую шаблонный шаблон nuget для представления моего приложения MVC3, что означает, что я должен использовать WebActivator для вызова метода статического класса, который, в свою очередь, создает загрузчик Ninject и подключается к MVC3.

Это прекрасно работает для контроллера, адаптеров и т. Д. Но я хочу иметь другой активированный класс Webactivator, который получает свои зависимости с помощью Ninject.

Я заставил его работать с плохим решением, но я бы предпочел более элегантное решение.

Сначала я проверяю, что мой класс Webactivator использует вызов PostApplicationStartMethod, поскольку модуль Ninject использует PreApplicationStartMethod. Я могу убедиться, что ninject был загружен и готов к работе. Затем в методе Start я делаю

var workers = DependencyResolver.Current.GetServices<IWorker>();

Чтобы получить мои зависимости, весь класс выглядит так

[assembly: WebActivator.PostApplicationStartMethod(typeof(SHB.DALA.Web.App_Start.WorkflowRunner), "Start")]

namespace SHB.DALA.Web.App_Start
{
    public static class WorkflowRunner 
    {
        public static void Start()
        {
            var workers = DependencyResolver.Current.GetServices<IWorker>();
            //Do stuff with worker collection
        }
    }
}

Должно быть более элегантное решение, верно?

2 ответа

Решение

WebActivator (на самом деле ASP.NET) не имеет никаких знаний о проекте Ninject и, следовательно, не может вводить какие-либо параметры. Для этого вам понадобится расширение Ninject WebActivator (так же, как у вас есть расширение Ninject MVC). Но, честно говоря, это небольшая загвоздка: вы хотите, чтобы WebActivator настраивал Ninject, и в то же время Ninject настраивал WebActivator.

Я могу придумать 2 возможных сценария для вас:

  1. оставьте код как есть - честно говоря, я не знаю, почему вам не нравится ваш WorkflowRunner учебный класс. Это хороший, маленький класс, никакой другой код не зависит от него. Вы получаете ваши ссылки через DependencyResolver который абстрагирует вас от самого Ninject, ваша инициализация рабочего процесса там хорошо инкапсулирована. Я не чувствую здесь ничего плохого, правда.

  2. Инициализируйте свои рабочие процессы в другом классе WebActivator, где настройка Ninject. Там вы знаете, что ваш Ninject инициализирован, и вы все еще можете хранить код инициализации рабочего процесса в отдельном классе.

Я бы, очевидно, выбрал 1. на вашем месте.

Если у вас уже работает загрузчик Ninject, вы уверены, что вам нужно другое решение? Для неконтроллерных зависимостей я использую класс BindingFactory, у которого есть метод GetInstance(). Это просто вызывает метод Get() объекта Kernel.

public class BindingFactory
{
    private static readonly IKernel Kernel = new StandardKernel(new DefaultServices());

    public static T GetInstance<T>()
    {
        return Kernel.Get<T>();
    }

    public static IController GetControllerInstance(Type controllerType)
    {
        return Kernel.Get(controllerType) as IController;
    }
}

Затем я использую NinjectControllerFactory, которая использует BindingFactory.

public class NinjectControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(RequestContext context, Type controllerType)
    {
        if (controllerType == null)
            return null;

        return BindingFactory.GetControllerInstance(controllerType);
    }
}

Так что я думаю, что вы могли бы просто адаптировать вашу текущую реализацию.

Другие вопросы по тегам