Ninject, Provider и Activator.CreateInstance - PullRequest
       34

Ninject, Provider и Activator.CreateInstance

5 голосов
/ 18 сентября 2010

Я довольно новичок в 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 (снова с использованием инжектора конструктора (если возможно)).Первая часть цепочки работает, вторая - нет.

1 Ответ

1 голос
/ 24 сентября 2010

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

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

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

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

...