Ninject, Провайдеры и Activator.CreateInstance

Я новичок в Ninject, но мне удалось успешно использовать его для DI с помощью настраиваемого провайдера.

Привязка инициализируется следующим образом

kernel = new StandardKernel();

kernel.Bind<IPatientRecordLocator>().ToProvider<PatientRecordLocatorProvider>();

и в настраиваемом провайдере я вызываю Activator.CreateInstance вот так

protected override IPatientRecordLocator CreateInstance(IContext context)
{
    var name = ConfigurationManager.AppSettings["PatientRecordLocator"];
    var typeName = name.Split(',')[0];
    var assemblyName = name.Split(',')[1];
    return Activator.CreateInstance(assemblyName, typeName).Unwrap() as IPatientRecordLocator;
}

(да, я знаю, что в приведенном выше коде нет обработки ошибок и т. д. :))

и все это работает как шарм.

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

[Inject]
public MockPatientRecordLocator (IContactAdapter contactAdapter)
{
    ...
}

Затем, чтобы Activator.CreateInstance работал, мне также нужно добавить конструктор без параметров в класс MockPatientRecordLocator, т.е.

public MockPatientRecordLocator() 
{
}

Итак, мой вопрос: как я могу заставить Ninject внедрить экземпляр класса, который реализует IContactAdapter, например, MockPatientRecordLocator? Я пробовал метод инъекции, но безуспешно.

Я забыл объяснить, что то, что я пытаюсь достичь, - это своего рода цепная инъекция, при которой экземпляр класса PatientRecordSummary вводится с экземпляром MockPatientRecordLocator (с использованием инъекции конструктора), и в указанный экземпляр MockPatientRecordLocator должен быть введен экземпляр IContactAdapter ( снова с помощью внедрения конструктора (если возможно)). Первая часть цепочки работает, вторая - нет.


person norgie    schedule 18.09.2010    source источник


Ответы (1)


Неплохо для первого вопроса!

Вы хотите использовать перегрузку Bind(Type), чтобы разрешить регистрацию того, что у вас нет статически доступного в контексте вашего Load() кода - делайте то, что вы делаете в своем провайдере (т. Е. Разрешая Type) заранее. Это позволит Ninject создать экземпляр объекта (без каких-либо требований к .ctor по умолчанию)

IIRC два или 3 моих последних ответа также коснитесь этого открытия / загрузки и найдите примеры, которые должны иметь отношение к вашему делу.

(И вам не нужно прибегать к [Inject] атрибутам, когда вам нужно что-то удалить)

person Ruben Bartelink    schedule 23.09.2010
comment
Привет, Рубен, спасибо за помощь (и комплимент). Стараюсь изо всех сил :-) В этой конкретной настройке я не использовал модули, но я перейду на их использование, чтобы мне было легче использовать Bind (). - person norgie; 19.10.2010