Мне нужно больше практических примеров Ninject - PullRequest
8 голосов
/ 07 февраля 2012

В прошлом я использовал быстрые подвески, которые представляют собой контроллер 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 ]

11 голосов
/ 08 февраля 2012

Глядя на ваш пример, становится ясно, что 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>();
}

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

5 голосов
/ 07 февраля 2012

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

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

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

...