Dependency injection (DI) is a term associated with object-oriented programming. It expresses that modules(objects, classes) get their dependencies - information or a certain behavior by calling methods - assigned by another, external instance, which is then also called injection. This injection is performed by a DI framework - such as the Spring or Unity frameworks. Closely related to the concept of Dependency Injection is the principle of Inversion of Control - the reversal of the flow of control. Three different types of dependency injection can be distinguished: setter injection, constructor injection and interface injection.
This also makes clear the levels at which injection takes place. The goal of using DI is to minimize dependencies between modules. Dependency Injection is also a concept, which can be used as part of a software architecture. The term Dependency Injection was coined and introduced by Martin Fowler. A detailed description by Martin Fowler on this topic is available at the link below.
Inversion of ControlSince the beginning of object orientation the principle of Inversion of Control (IoC) is an aspect discussed in this context. But only in the course of the further development of object-oriented programming languages and concepts, such as in the environment of C++, Java, Python and others, this topic became more popular again; although the principle is by no means a new invention. Now Inversion of Control is to be understood as a general feature offrameworks, which in common parlance is also called the so-called Hollywood principle "Don't call us, we'll call you!". This means that the responsibility for program execution lies on the side of the framework - which is also referred to as reverse control flow. This means that the responsibility explicitly does not lie with the components developed on the basis of this framework. To do this, the corresponding modules must implement so-called callback methods (callbacks). Here, the runtime environment for the framework is provided by a container. The callbacks give the framework during runtime the possibility of passing - the injection - of information to these modules or also to realize by injection a certain behavior of modules by calling their methods. Thus, the life cycle of a complete module can also be influenced from the outside by the callbacks.
Dependency Injection (DI) is a special form of the Inversion of Control principle, which was defined and introduced by Martin Fowler. The background was the predominant use of the Inversion of Control principle for the injection of references to required resources by lightweight frameworks like Spring and containers like PriceContainer or Excalibur. DI allows services of so-called service factories to be hidden from the outside world. In object orientation, factories are objects that can in turn create other objects. In this way, the use of DI should not create dependencies between modules and classes. In any case, the responsibility for the interaction of modules lies with the framework, which requires further information regarding the configurations of these modules. These are either integrated directly into the code or are available separately in a configuration file - often an XML file. The transfer of used objects to objects to be used will therefore always be based on this configuration information. The choice of configuration depends on the individual case.
The different forms of Dependency Injection
There are three fundamentally different forms of dependency injection when passing modules:
Setter Injection The DI framework uses the setter method to ensure that a required module is injected.
Constructor Injection In constructor injection, the required modules are passed as arguments to the constructor of a class.
Interface Injection Here, the injection is done via explicitly implemented interfaces on the side of the used module as well as on the side of the using module. In practice, however, this possibility of injection is avoided, since the implementation of the interfaces in turn results in dependencies.
DI can be used advantageously when merging an application from different modules. Different types of configuration can be supported by the procedure. By assigning modules to a configuration, the framework can be used to create any type of configuration, for example, special server configurations or test configurations. The focus of Dependency Injection is on the decoupling of modules that otherwise have no contact. Dependency Injection should not be considered a replacement for factories. However, when modules are configured via separate files, there is also a major disadvantage for the developer - the processes of an application can no longer be traced without precise knowledge of the configuration file.
For different programming languages and platforms there are various frameworks that support Dependency Injection:
- For Java: Spring, EJB 3.0, Seam, Guice.
- For .NET: Unity, Ninject, ObjectBuilder, LightCore, PicoContainer, Structuremap.
- For Python: PyContainer.
- For Ruby: Needle,Copland.
- For C++: DSM.
- For PHP5: Garden, Symfony Components, Stubbles IoC.