I need a little more help to "get" how a DI framework like Ninject moves past the basics.
Take the Ninject sample:
class Samurai {
private IWeapon _weapon;
[Inject]
public Samurai(IWeapon weapon) {
_weapon = weapon;
}
public void Attack(string target) {
_weapon.Hit(target);
}
}
Without a DI framework (i.e. the [Inject] references above) a referencing class would look something like:
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");
}
}
...where you're newing up everything. Yes, you've removed the dependency in Samurai, but now you've got a dependency one step further up the chain. Simple.
With Ninject, you get rid of newing up everything by:
class Program {
public static void Main() {
IKernel kernel = new StandardKernel(new WarriorModule());
Samurai warrior = kernel.Get<Samurai>();
warrior.Attack("the evildoers");
}
}
HOWEVER, this is my area of confusion: without making some kind of service locater to take care of efficiently newing up the applicable kernel and module (i.e. .IoC.TypeResolver.Get<>()), what is a) the best way to not have to new up kernels everywhere (service locater references everywhere?), and b) more importantly, when you've got a big long chain with dependencies with dependencies of their own, you take it to the extreme of passing injections all the way up in something that I'm sure is a serious anti-pattern (a friend called it "hot-potato dependency injection" anti-pattern).
In other words, I thought part of the DI framework magic is that you don't have to keep inserting dependencies all the way up the chain (i.e. your your first reference containing 10 parameters in its constructor, none of which have anything to do with anything until much further along the chain) - where's the magic or the solution to my confusion so that dependencies don't either continually get referenced up and up the chain, or service locater references spread everywhere.
Further muddying the waters for me is if using a DI framework, what's the best way to deal with a scenario where a referenced class needs an IList which would typically be put in the constructor (i.e. new ReferencedClass(myList)) as that, other than in simple cases like a string database connection string, doesn't fly. Just make a property and set it after newing it up/DI Framework service locating? I.e.
var referencedClass = IoC.Get<IReferencedClass>();
referencedClass.MyList = myList;
All in all, I think this is a post I'll likely be embarrassed about after I get it, but right now, I've hit my head too many times against the wall trying to determine the best approach.