2012-02-07 1 views
8

В прошлом я использовал swiftsuspenders, который является контроллером IOC для ActionScript 3. В основном первая версия switchfsuspender имела нечто похожее на ядро ​​Ninject, которое называлось инжектором.Мне нужно больше практических примеров 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.

ответ

11

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

К инвертировать элемент управления этой зависимости, вам необходимо будет ввести эту зависимость в SomeClass. Как Remo Gloor has indicated, стандартный способ сделать это с помощью 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>(); 
} 

Ядро затем сможет пройти t его цепь зависимостей и внедрить их все.

+0

Спасибо за ответ, это имеет смысл, но пока оно правильно, оно просто утверждает, что все зависимости должны быть известны заранее. Что происходит, когда это невозможно? (конечно, то, что я говорю, имеет смысл только в том случае, если объекты создаются динамически, что может произойти) – sebas

+0

предположим, что SomeClass должен создать определенное число динамических объектов. Как SomeClass становится Level, и он должен создать 30 звезд. звезды имеют несколько зависимостей, как уровень может вводить эти зависимости в звезды с помощью ядра? – sebas

+0

Это хороший вопрос, и вы выходите за рамки простых вопросов инъекции зависимостей, на которые можно ответить в этом формате. Такая ситуация (сложное создание объекта) имеет тенденцию требовать еще одну деталь, поэтому Ремо упомянул Фабрики в своем ответе. Вы должны исследовать либо создание фабрики звездообразования, либо ввести ее в SomeClass, либо Ninject разрешить звезды, используя собственный метод Factory или Bind(). ToProvider(). –

5

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

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

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

+2

Hi Remo! Спасибо за ответ. Вы предоставили полезную информацию, но это не то, что я хотел знать. Вы говорите мне, что Get не следует использовать в качестве локатора сервисов, но то, что я попросил, было больше: допустим, у меня есть класс, который должен создать команду в одном из своих методов. Предположим, что команде нужны определенные зависимости, а ядро ​​определено вне класса, создающего команду. Как я должен использовать ядро ​​для ввода зависимостей внутри этой команды? Должен ли я сначала ввести ядро ​​в класс, который создает команду? – sebas

+0

моя проблема что-то похожее на это http://stackoverflow.com/questions/2862698/ninject-shared-di-ioc-container, но я бы не использовал какой-либо статический класс, я предпочитаю вводить ядро ​​в этот момент. – sebas

+0

Вы должны добавить пример кода на свой вопрос о том, что вы хотите сделать. Все остальное просто догадывается. Обычно зависимости должны передаваться с использованием инъекции конструктора, которая выполняется автоматически с помощью Ninject. –

 Смежные вопросы

  • Нет связанных вопросов^_^