Ninject: общий контейнер DI/IoC

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

public class GeneralDIModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDataBroker>().To<DataBroker>().InSingletonScope();
    }
}

public abstract class IoC
{
    private static IKernel _container;

    public static void Initialize()
    {
        _container = new StandardKernel(new GeneralDIModule(), new ViewModelDIModule());
    }

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

Я заметил, что есть метод Resolve. В чем разница между Resolve и Get?

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

Существует метод Inject, но он говорит, что жизненный цикл экземпляра не управляется?

Может ли кто-нибудь поставить меня в правильном направлении?

Как я могу зарегистрировать, отменить регистрацию объектов и сбросить контейнер.


person joblot    schedule 19.05.2010    source источник
comment
Привет Ян Спасибо за ответ. Несколько вопросов. Создает ли метод Get новый экземпляр типа с временным образом жизни? - Если я создам имитируемый экземпляр типа, используя какую-то фиктивную среду, скажем, Rhino Mocks и внедрить ее в ядро, будет ли последующий Get создавать новый экземпляр этого типа или они будут возвращать тот же экземпляр? - Отличается ли ninject.moq от RhinoMocks? Спасибо   -  person joblot    schedule 19.05.2010
comment
Если вы не укажете образ жизни или не укажете .InTransientScope(), каждый вызов .Get будет возвращать новый экземпляр. Если можете, используйте Moq или RhinoMocks перед Ninject.Moq (который использует Moq). Moq и RhinoMocks — хорошие фреймворки для имитации.   -  person Ian Davis    schedule 20.05.2010
comment
поэтому, если я укажу SingletonScope при привязке в модуле и введу имитированный экземпляр типа, каждый вызов Get будет возвращать один и тот же экземпляр? Что это значит, когда говорится, что Inject внедряет указанный существующий экземпляр, не управляя его жизненным циклом? Я также понял, что в версии Ninject для Silverlight нет версии Load, которая принимает строковый аргумент, который можно использовать для динамической загрузки модулей Load (*.dll). Как я могу добиться динамической загрузки в Silverlight. Спасибо   -  person joblot    schedule 20.05.2010
comment
Причина, по которой я хочу загружать модули динамически, заключается в том, чтобы избежать проблемы циклической зависимости. У меня есть следующие слои View --> ViewModel --> DataProvider --> ServiceClient (прокси wcf). Теперь мне нужен статический контейнер IoC, который можно использовать на этих уровнях. Я хочу сделать мой View пригодным для тестирования, и для этого мне придется внедрить различные зависимости в разные слои, а также смоделировать эти зависимости. Теперь проблема, с которой я сталкиваюсь, заключается в том, где объявлять и загружать модули ninject. Я думаю, именно здесь Castle Windsor силен, по крайней мере, вы можете объявлять привязку извне в xml и загружать их динамически.   -  person joblot    schedule 20.05.2010


Ответы (1)


Ninject по умолчанию связывает компоненты в переходном образе жизни, и Ninject не отслеживает переходные экземпляры. Resolve используется внутри и не должен использоваться вашим кодом, если вы действительно не знаете, что делаете. Если вы хотите имитировать свой контейнер, используйте расширение ninject.moq на github. Метод инъекции, о котором вы говорите, предназначен для экземпляров, которые вы создали сами. Используйте методы Get и TryGet.

person Ian Davis    schedule 19.05.2010
comment
В Ninject 2 образ жизни по умолчанию одноэлементный, а не временный. - person Mauricio Scheffer; 19.05.2010
comment
Мы изменили его более года назад на переходный. Вы можете увидеть это в строке 104: github.com/ninject/ninject/blame/master/src/Ninject/Planning/ - person Ian Davis; 19.05.2010
comment
Привет Ян Спасибо за ответ. Несколько вопросов. Создает ли метод Get новый экземпляр типа с временным образом жизни? - Если я создам имитируемый экземпляр типа, используя какую-то фиктивную среду, скажем, Rhino Mocks и внедрить ее в ядро, будет ли последующий Get создавать новый экземпляр этого типа или они будут возвращать тот же экземпляр? - Отличается ли ninject.moq от RhinoMocks? Спасибо - person joblot; 19.05.2010
comment
Ой, извините, не знал, что он был изменен обратно на переходный. - person Mauricio Scheffer; 19.05.2010