Мне нужна дополнительная помощь, чтобы «понять», как фреймворк DI, такой как Ninject, выходит за рамки основ.
Возьмите образец Ninject:
class Samurai {
private IWeapon _weapon;
[Inject]
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
public void Attack(string target) {
_weapon.Hit(target);
}
}
Без структуры DI (т.е. ссылок на [Inject] выше) ссылающийся класс выглядел бы примерно так:
class Program {
public static void Main() {
Samurai warrior1 = new Samurai(new Shuriken());
Samurai warrior2 = new Samurai(new Sword());
warrior1.Attack("the evildoers");
warrior2.Attack("the evildoers");
}
}
... где вы все обновляете. Да, вы удалили зависимость в Samurai, но теперь у вас есть зависимость на один шаг дальше по цепочке. Простой.
С Ninject вы избавитесь от всего нового:
class Program {
public static void Main() {
IKernel kernel = new StandardKernel(new WarriorModule());
Samurai warrior = kernel.Get<Samurai>();
warrior.Attack("the evildoers");
}
}
ОДНАКО, это моя область путаницы: без создания какого-либо средства поиска сервисов, чтобы позаботиться об эффективном обновлении применимого ядра и модуля (т.е. .IoC.TypeResolver.Get ‹> ()), что является а) лучшим способом не нужно обновлять ядра повсюду (повсюду ссылки на поисковики служб?), и б) что более важно, когда у вас есть большая длинная цепочка с зависимостями с собственными зависимостями, вы доводите ее до крайности, проходя инъекции на всем пути в чем-то, что, я уверен, является серьезным анти-шаблоном (друг назвал это анти-шаблоном «инъекции горячих зависимостей»).
Другими словами, я думал, что часть магии фреймворка DI заключается в том, что вам не нужно постоянно вставлять зависимости по всей цепочке (т.е. ваша первая ссылка, содержащая 10 параметров в своем конструкторе, ни один из которых не имеет ничего общего с что угодно, пока не будет намного дальше по цепочке) - где же магия или решение моей путаницы, так что зависимости не будут постоянно ссылаться вверх и вверх по цепочке, а ссылки на поисковики сервисов распространяются повсюду.
Дальнейшая путаница для меня заключается в том, что при использовании структуры DI, как лучше всего справиться со сценарием, когда указанному классу нужен IList, который обычно помещается в конструктор (то есть новый ReferencedClass (myList)) как это, кроме в простых случаях, таких как строка подключения к базе данных, не летает. Просто создайте свойство и установите его после создания / обнаружения службы DI Framework? Т.е.
var referencedClass = IoC.Get<IReferencedClass>();
referencedClass.MyList = myList;
В общем, я думаю, что это пост, который меня, вероятно, смущает, когда я его получу, но прямо сейчас я слишком много раз бился головой об стену, пытаясь определить лучший подход.