Or instead of creating the object themselves, do they somehow intercept or hook into object creation (for example, a Controller instantiated by the MVC framework) and pass in whatever dependencies they're required to?
I realize they need to do something when the object is created in order to use constructor injection, but I am unclear as to whether the containers need to do the creating, or if they somehow intercept the object's creation.
Whatever the answer is, do all DI containers do it this way?
I realize this question is probably obvious to most familiar with tools like StructureMap, Unity, Ninject, etc... but I am new to them and realized I don't really know how they work under the covers. I have scoured the internet and can't find a good answer.
In all the DI/IoC containers I've used, the containers do the creating themselves. You won't find any production code using
new Something(dependency1, dependency2)
... instead, you'll have code implicitly or explicitly asking the container for "an instance ofSomething
" (maybe as a dependency of something else). The container then takes care of either reusing an instance ofSomething
, based on how it's configured (and howSomething
is annotated).Where you do often explicitly call the constructor is in the test for
Something
, at which point the container may well not exist at all - or you may have a test-specific configuration which allows you to ask for some of the dependencies in a stock way, and maybe provide other dependencies in a test-specific way. (In some cases, you still won't need to call the constructor explicitly... if you have a test configuration for the container, e.g. using fake storage for everything, then you may still just need to ask for an instance ofSomething
to use in your tests.)There are at least three slightly different approaches.
A most common one is when the container calls the constructor by itself, using some kind of reflection and recursive approach to parameter resolving.
Sometimes however, existing instances (created manually) are passed to the container to build them up which is to satisfy these dependencies that can be satisfied otherwise than by constructor injection (otherwise here means "with property injection"). This could not be what you ask about, though.
The last approach that is often used is when a factory method is registered in the container. The container doesn't call the constructor in this approach then, rather, it calls the factory method and the method is implemented manually, which means that the factory's code calls the constructor directly: