DI Containers
A DI container is an injector object that injects the dependencies into a dependent object. As we have seen in the previous example, we don't necessarily need a DI container in order to implement Dependency Injection. However, in more complex scenarios, a DI container can save a lot of time and effort by automating most of the tasks that we had to do manually. In real world applications, a single dependant class can have many dependencies, each of which have their own dependencies that forms a large graph of dependencies. A DI container should resolve the dependencies, and this is where the decision of selecting a concrete class for the given abstraction should be made. This decision is made by a mapping table, which is either based on a configuration file or is programmatically defined by the developer. We can see an example for both here:
<bind service="ILogger" to="ConsoleLogger" />
This one is an example of code-based configuration:
Bind<ILogger>().To<ConsoleLogger>();
We can also define conditional rules instead of just mapping a service to a concrete type. We will discuss this feature in detail in Chapter 2, Getting Started with Ninject.
A container has the responsibility of dealing with the lifetime of the created objects. It should know how long an object should be kept alive, when to dispose of it, in what condition to return the existing instance, and in what condition to create a new one.
Note
DI Containers are also known as IoC Containers.
There are other DI Container besides Ninject. You can find a list of them in Scott Hanselman's blog (http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx). Unity, Castle Windsor, StructureMap, Spring.NET, and Autofac are a few of them: