Мультиинъекция Ninject не такая жадная, как я мог подумать! Как придешь?

Если у меня есть класс с ctor, настроенным для множественной инъекции, например:

public Shogun(IEnumerable<IWeapon> allWeapons)
{
    this.allWeapons = allWeapons;
}

И привязки настроены так:

Bind<IWeapon>().To<Sword>();
Bind<IWeapon>().To<Dagger>().WhenInjectedInto<Shogun>();

Тогда я мог бы ожидать, что Сёгун будет построен с введенными обоими видами оружия? Но это не так - он получает только Кинжал.

Если я добавлю следующую привязку:

Bind<IWeapon>().To<Sword>();
Bind<IWeapon>().To<Dagger>().WhenInjectedInto<Shogun>();
Bind<IWeapon>().To<Shuriken>().WhenInjectedInto<Shogun>();

Затем Сёгун получает Кинжал и Сюрикен. WhenInjectedInto<T>() похоже, что он должен только ограничивать привязку, к которой он применяется, и не влиять на другие привязки. Я считаю такое поведение вводящим в заблуждение.

Может кто-нибудь объяснить, что здесь происходит?


person James World    schedule 04.09.2011    source источник
comment
Мне очень жаль, но почему вы ожидаете, что Shogun (в первом случае) будет сконструирован с введенными обоими видами оружия, когда вы явно просите привязать IWeapon к Dagger при введении в Shogun?   -  person virtualmic    schedule 04.09.2011
comment
Потому что я также просил, чтобы IWeapon был привязан к Sword. Почему привязка IWeapon к Dagger в конкретном случае предотвращает общую привязку? Это означает, что я могу написать код, который создает конкретную привязку и нарушает более общие привязки, созданные где-то еще. Это кажется опасным и нелогичным.   -  person James World    schedule 04.09.2011
comment
Но ведь это превзошло бы цель WhenInjectedInto, не так ли? Я новичок в ninject, но, насколько я понимаю, цель этой функции - иметь дело с конкретными случаями, как вы упомянули, обработанными. Вы хотите, чтобы IWeapon был привязан к Sword в целом; однако при введении в Shogun вы хотите, чтобы он был привязан к Dagger. Если вы хотите, чтобы в Shogun были введены и Sword, и Dagger, WhenInjectedInto не следует использовать, ИМХО.   -  person virtualmic    schedule 04.09.2011
comment
Хотя мы занимаемся заявлением об отказе от ответственности, я также новичок в Ninject. :) Я понимаю, о чем вы говорите, и, возможно, это просто вопрос вашего мнения - я думаю, что чтение WhenInjectedInto немного неоднозначно. Я читал это как относящийся к реализации (то есть Dagger или Sword), а не к контракту (то есть IWeapon), а не как к сообщению, когда вводите IWeapon в Shogun, вводите кинжал. Читать таким образом имеет смысл.   -  person James World    schedule 04.09.2011
comment
Однако мне все еще не нравится, как затем сбрасываются общие привязки. :) Ничего не могу поделать, но вижу, что в сложных приложениях он может неожиданным образом ломать вещи.   -  person James World    schedule 04.09.2011
comment
Итак, тогда я должен опубликовать свой комментарий в качестве ответа? :)   -  person virtualmic    schedule 04.09.2011
comment
Думаю, мне бы хотелось увидеть ответ, который конкретно объяснял бы механизм происходящего. Я замечаю, что могут быть применены и другие условия When, которые, кажется, вполне удачно сочетаются с теми, которые у меня уже есть, например: Bind<IWeapon>().To<BoStaff>().When(x => true); Это не упоминает Shogun, но все же появляется в мульти-инъекции, когда Sword этого не делает.   -  person James World    schedule 04.09.2011


Ответы (1)


Это ошибка - GetAll не вернет все экземпляры, если условные и безусловные привязки смешаны.

Это исправлено в версии версии 2.4.0.0.

person Remo Gloor    schedule 04.09.2011
comment
Значит, я ошибался! (в комментариях к вопросу). Спасибо за вопрос, Джеймс, и за разъяснения, Ремо! - person virtualmic; 05.09.2011
comment
Хорошая работа! Я рад, что это была ошибка, а не преднамеренная! - person James World; 05.09.2011
comment
Просто добавлю, что на момент написания текущая версия выпуска - 2.2.0.0, поэтому любой, кого это коснется, должен сознательно получить последнюю сборку. - person James World; 05.09.2011