What is dependency injection

Dependency Injection

Dependency injection is a software design pattern in which one or more dependencies (or services) are injected, or passed by reference, into a dependent object (or client) and are made part of the client’s state. The pattern separates the creation of a client’s dependencies from its own behavior, which allows program designs to be loosely coupled and to follow the dependency inversion and single responsibility principles. It directly contrasts the service locator pattern, which allows clients to know about the system they use to find dependencies.

An injection is the passing of a dependency(a service) to a dependent object(a client). The service is made part of 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.

In dependency injection only a single instance of a dependency is used.

Advantages

Because dependency injection doesn’t require any change in code behavior it can be applied to legacy code as a refactoring. The result is clients that are more independent and that are easier to unit test in isolation using stubs or mock objects that simulate other objects not under test. 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.
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.
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. Plugins are often developed by third party shops that never even talk to the developers who created the product that uses the plugins.

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 typically requires more lines of code to accomplish the same behavior legacy code would.
Dependency injection diminishes encapsulation by requiring users of a system to know how it works and not merely what it does.

For more information please go through http://en.wikipedia.org/wiki/Dependency_injection    

By applying Dependency Injection, our code becomes significantly simpler, easy to understand and easier to test. An application which is made up of two or more classes that collaborate with each other to perform some business logic.

Traditionally each object is responsible for obtaining its own references to objects it collaborates with. This can lead to highly-coupled and hard to test.

For example, consider the below class

The class Vehicle instantiates a truck as this class needs truck. So the class Vehicle depends on class Truck. So the class Vehicle cannot carry its work without a Truck. Therefore, Vehicle has a dependency on Truck Truck.

The class Vehicle itself instantiates a Truck. Therefore the Vehicle class is said to satisfy its own dependencies. When a class satisfies its own dependencies it automatically also depends on the classes it satisfies the dependencies with. In this case Vehicle now also depends on Truck, and on the one hardcoded string value passed as a parameter to the Truck constructor. You cannot use a different value for this string, nor use a different implementation of the Truck interface, without changing the code.

As you can see, when a class satisfies its own dependencies it becomes inflexible with regards to these dependencies. This is not a good design. This means, that if you need to change the dependencies you will have to change the code. In this example, if you need to use a different truck or car, you will need to change the Vehicle class. If you have many classes implemented like this you will need to change them all. In addition, you cannot unit test the Vehicle class using a mock Truck. You can only use the Truck.

Notice how the Truck instantiation is moved into a constructor. The constructor takes one parameter which is the string value needed by the Truck. Though the Vehicle class still depends on this value, it no longer satisfies the dependency itself. It is provided by whatever class creating a Vehicle instance. The value is said to be injected into the Vehicle constructor. Hence the term dependency injection. It is now possible to change the name used by the Vehicle class, without changing the Vehicle class.

Dependency injection is not restricted to constructors. We can also inject dependencies using setter methods, or directly into public fields.

The Vehicle class can still be made more independent. It still depends on both the Truck class. There is no need for it to depend on more than the Car interface. This can be achieved by injecting a Car into the constructor instead of the string parameter. Here is how that looks:

Now the Vehicle class no longer depends on the Truck class, or the one string needed by the Truck constructor. We can now inject any truck or car into the Vehicle constructor.

Decoupling using Interfaces

A common technique used to reduce coupling is to hide implementation details behind interfaces so that the actual implementation class can be swapped out without impacting the client class. For example, suppose we were to create

Then, we change Truck to implement this interface.

and

Now we can use Vehicle class to use any Car type whether it is a Truck or Bus.

This dependency injection pattern is continued all the way up the layers of our application, from the lowest data accessing layers up to the user interface (if any).

Thanks for your reading.

 

Soumitra

Software Professional, I am passionate to work on web/enterprise application. For more information please go to about me. You can follow on Twitter. You can be a friend on Facebook or Google Plus or Linkedin

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.