In the past, I used swiftsuspenders that is an actionscript 3 IoC controller. Basically the first version of switfsuspender had something similar to the Ninject kernel that was called injector.
If I wanted to create an application injector (with let's say the most relevant mappings to be used throughout the application), I had to inject the injector itself in the application classes.
I am wondering now what is the practice to use kernel.get<> among several classes in the application. Should I inject the kernel itself?
Personally I'd rather use kernel.inject but if I can do kernel.inject I can really likely inject the dependencies manually, which is probably better (kiss).
Test cases are nice, but they are far from the real practical issues, so I hope you can help me to clarify this point. Thank you.
Edit: I noticed that some people talk about "root container", It seems like it is the concept I am looking for. How should I setup a root container and let the other application classes know it?
Edit2 Sample code (please forgive errors, it is just for example sake):
class SomeClass
{
public SomeClass()
{
Command cmd = new Command();
cmd.execute();
}
}
class SomeOtherClass:ISomeOtherClass
{
public void allright()
{
//right
}
}
class Command
{
ISomeOtherClass dependency;
void execute()
{
dependency.allright();
}
}
Program.Main()
{
IKernel kernel = new StandardKernel();
kernel.Bind<SomeClass>().ToSelf().InSingletonScope();
kernel.Bind<ISomeOtherClass>().To<SomeOtherClass>();
SomeClass sc = kernel.Get<SomeClass>();
}
I did not test this yet, because I am still fighting with some initialization issues, but my question is, how can the command class know about SomeOtherClass? My current hypothesis is to inject the kernel in SomeClass and use the method Inject.
Looking at your example, it is clear that
SomeClass
is not built with Inversion of Control in mind; the tip-off being that it has a dependency onCommand
, but control of that dependency is maintained insideSomeClass
itself. (Command cmd = new Command();
)To invert the control of that dependency, you would need to have a way to inject that dependency into SomeClass. As Remo Gloor has indicated, the standard way of doing that with Ninject is through the constructor.
To do so, you might change SomeClass to something like this:
Likewise you would need your Command to advertise its dependency:
Then you would register your Command binding in the kernel, perhaps like:
The kernel would then be able to walk the dependency chain and inject them all.
Use constructor injection wherever possible and Factories whenever there is a good reason not to create the instances together with the object that depend on them.
kernel.Inject
should only be used when you are not in change of the creation of the object. E.g. a WebFormkernel.Get
should be used exactly once in your composition root (e.g. Program.Main or MVC3.DependencyResolver) to create your application.