Мне нужно больше практических примеров Ninject

В прошлом я использовал swiftsuspenders, который является контроллером ActionScript 3 IoC. По сути, первая версия switfsuspender была похожа на ядро ​​Ninject, которое называлось инжектором.

Если я хотел создать инжектор приложения (скажем, с наиболее релевантными сопоставлениями, которые будут использоваться в приложении), я должен был внедрить сам инжектор в классы приложения.

Теперь мне интересно, какова практика использования kernel.get<> среди нескольких классов в приложении. Стоит ли вводить само ядро?

Лично я предпочел бы использовать kernel.inject, но если я могу сделать kernel.inject, я действительно могу ввести зависимости вручную, что, вероятно, лучше (поцелуй).

Контрольные примеры хороши, но они далеки от реальных практических вопросов, поэтому я надеюсь, что вы можете помочь мне прояснить этот момент. Спасибо.

Редактировать: я заметил, что некоторые люди говорят о "корневом контейнере", кажется, что это концепция, которую я ищу. Как мне настроить корневой контейнер и сообщить об этом другим классам приложения?

Пример кода Edit2 (пожалуйста, прости за ошибки, это только для примера):

class SomeClass
{
    public SomeClass()
    {
        Command cmd = new Command();

        cmd.execute();
    }

}

class SomeOtherClass:ISomeOtherClass
{
 public void allright()
 {
    //right
 }
}

class Command
{
   ISomeOtherClass dependency;

   void execute()
   {
    dependency.allright();
   }

}


Program.Main()
{
    IKernel kernel = new StandardKernel();

    kernel.Bind<SomeClass>().ToSelf().InSingletonScope();
    kernel.Bind<ISomeOtherClass>().To<SomeOtherClass>();

    SomeClass sc = kernel.Get<SomeClass>();
}

Я еще не проверял это, потому что я все еще борюсь с некоторыми проблемами инициализации, но мой вопрос, как командный класс может знать о SomeOtherClass? Моя текущая гипотеза состоит в том, чтобы внедрить ядро ​​в SomeClass и использовать метод Inject.

2 ответа

Решение

Глядя на ваш пример, становится ясно, что SomeClass не построен с учетом инверсии контроля; наводка на то, что он имеет зависимость от Command, но контроль над этой зависимостью сохраняется внутри SomeClass сам. (Command cmd = new Command();)

Чтобы инвертировать контроль над этой зависимостью, вам нужно иметь способ внедрить эту зависимость в SomeClass. Как указал Remo Gloor, стандартный способ сделать это с помощью Ninject - через конструктор.

Для этого вы можете изменить SomeClass на что-то вроде этого:

class SomeClass
{
    private ICommand _command;

    public SomeClass(ICommand injectedCommand)
    {
        _command = injectedCommand;
        _command.execute();
    }

}

Точно так же вам понадобится ваша команда для объявления ее зависимости:

class Command
{
   private ISomeOtherClass _dependency;

   public Command(ISomeOtherClass injectedSomeOtherClass)
   {
        _dependency = injectedSomeOtherClass;
   {

   void execute()
   {
      _dependency.allright();
   }
}

Затем вы должны зарегистрировать привязку вашей команды в ядре, например:

Program.Main()
{
    IKernel kernel = new StandardKernel();

    kernel.Bind<SomeClass>().ToSelf().InSingletonScope();
    kernel.Bind<ICommand>().To<Command>();
    kernel.Bind<ISomeOtherClass>().To<SomeOtherClass>();

    SomeClass sc = kernel.Get<SomeClass>();
}

Тогда ядро ​​сможет пройти цепочку зависимостей и внедрить их все.

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

kernel.Inject следует использовать только тогда, когда вы не изменяете создание объекта. Например, веб-форма

kernel.Get следует использовать ровно один раз в корне композиции (например, Program.Main или MVC3.DependencyResolver) для создания приложения.

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