Dependency injection (DI) is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments and properties that are set on the object instance after it is constructed. (Factory methods may be considered a special case of providing constructor arguments for the purposes of this description). The container injects these dependencies when it creates the object. This process is fundamentally the inverse to the case when the object itself is controlling the instantiation or location of its dependencies by using direct construction of classes, or the Service Locator pattern. The inverting of this responsibility is why the name Inversion of Control (IoC) is used to describe the container’s actions.
Code is cleaner when using DI and decoupling is more effective when objects are provided with their dependencies. The object does not look up its dependencies, and does not know the location or class of the dependencies. Long sections of initialization code that you used to hide in a #region tag simply go away, and are placed by container configuration metadata. One can also consider this clean up an application of the principal of Separation of Concerns. Before using DI, your class was responsible for business logic AND its configuration, it was concerns with doing more than one thing. DI removes the responsibility of configuration from the class, leaving it only with a single purpose, as the location of business logic. Furthermore, since your class does not know the location of its dependencies these classes also become easier to test, in particular when the dependencies are interfaces or abstract base classes allowing for stub or mock implementation to be used in unit tests.