Dependency Injection
Dependency Injection is a software design pattern that implements inversion of control for resolving dependencies. A dependency is an object that can be used. An injection is the passing of a dependency to a dependent object that would use it. The service is made part of the client's state. Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.
Dependency
injection allows a program design to follow the dependency inversion principle. The
client delegates the responsibility of providing its dependencies to external
code. The client is not allowed to call the injector code. It is the
injecting code that constructs the services and calls the client to inject
them. This means the client code does not need to know about the injecting
code. The client does not need to know how to construct the services. The
client does not need to know which actual services it is using. The client only
needs to know about the intrinsic interfaces of the services because these
define how the client may use the services. This separates the responsibilities
of use and construction.
There
are three common means for a client to accept a dependency injection: setter-, interface- and constructor-based injection.
·
Constructor Injection:
the dependencies are provided through a class constructor.
·
Setter Injection:
the client exposes a setter method that the injector uses to inject the
dependency.
· Interface Injection:
the dependency provides an injector method that will inject the dependency into
any client passed to it. Clients must implement an interface that exposes a setter method that accepts the dependency.
Advantages
·
Dependency injection allows a client
the flexibility of being configurable.
·
Dependency injection can be used to
externalize a system's configuration details into configuration files allowing
the system to be reconfigured without recompilation. Separate configurations
can be written for different situations that require different implementations
of components. This includes, but is not limited to, testing.
·
Because dependency injection doesn't
require any change in code behavior it can be applied to legacy code as a refactoring.
·
This ease of testing is often the
first benefit noticed when using dependency injection.
·
Dependency injection allows a client
to remove all knowledge of a concrete implementation that it needs to use. This
helps isolate the client from the impact of design changes and defects. It
promotes reusability, testability and maintainability.
·
Reduction of boilerplate code in the application objects, since all
work to initialize or set up dependencies is handled by a provider component.
·
Dependency injection allows concurrent
or independent development. Two developers can independently develop classes that use each other, while only
needing to know the interface the classes will communicate through.
·
Dependency Injection decreases
coupling between a class and its dependency.
Disadvantages
·
Dependency injection can make code
difficult to trace (read) because it separates behavior from construction. This
means developers must refer to more files to follow how a system performs.
·
Dependency injection forces complexity
to move out of classes and into the linkages between classes which might not
always be desirable or easily managed.
·
Ironically, dependency injection can
encourage dependence on a dependency injection framework.