What is Dependency Injection? (with java examples)

Dependency Injection

We are going to cover the concept of dependency injection (DI) in a very simple  and clear manner. First let’s take a simple definition.


  1. What is Dependency Injection?
  2. Problem with Conventional Method
  3. Types of Dependency Injection
  4. How Dependency Injection Works
  5. Concept of Inversion of Control (IoC)
  6. Benefit of Dependency Injection


1. What is Dependency Injection?

Dependency Injection is a design pattern whereon object provides another object with dependencies. So the easiest way to understand it to to use an example. But let’s first understand what dependency means.

Well, dependency means something needs something else to function. For example, a computer needs a hard disk, keyboard, memory etc.

The computer class is represented below.

public class Computer {
	private HardDisk harddisk = new HitachiHD();
	private RAM ram = new SDRAM();
	//additional codes


Class with no Dependency Injection


If you look at the computer class, you will notice that the the computer class creates its own HardDisk and RAM. You do this using the new keyword


2. The Problem with Conventional Method

The computer object uses the HitachiHD (it depends on the HitachiHD). Now assuming that in future we want to use SeagateHD. It means you need to recreate the class with the new SeagateHD. The could be very difficult if the class in not simple or there are many classes.

This problem is solved by dependency injection. With Dependency injection, you don’t need to create this dependent classes inside the class. You simply get them. They are injected at runtime.


3. Types of Dependency Injection

Basically, there are three types of dependency injection as outlined below.

a. Constructor Injection

In this case, the dependencies are provided through a class constructor

b. Setter Injection

In this type, the client provides a setter method that is used to inject the dependency into the class that requires it.

c. Interface Injection

Here, the dependency (dependent class) provides a method that can be called. The method takes the client that requires the dependency and provides the client with the required dependency.


public class Computer {
	private HardDisk harddisk;
	private RAM ram;
	 * With dependency injection, you don't need to instantiate
	 * the dependencies
	 * They are instantiated in another code and provided to this class
	 * when needed
	//Constructor based DI
	public Computer(HardDisk harddisk, RAM ram) {
		this.harddisk = harddisk;
		this.ram = ram;
	//Setter based DI
	void setHardDisk(HardDisk harddisk) {
		this.harddisk = harddisk;

	//other codes	

Class with Dependency Injection


4. How  Dependency Injection  works

So you can see that in this class, there is new instantiation of new dependencies. It is then the work of DI to:

  • Create (instantiate) new objects
  • Determine which classes require these objects
  • Provide them with these object when needed


If therefore, there are changes in these objects, you don’t have to re-write the class. Dependency Injection takes care of it! It doesn’t have to concern the class. The class just gets the updated object.


5. Concept of Inversion of Control(IoC)

This is the principle behind dependency injection. It simply states that a class should not configure its dependencies statically (tight-coupling). The configuration should be done by another class from the outside (loose-coupling). So we are decoupling the class from it’s dependencies.

According to this principle, a class should focus on performing required action and not on creating objects. Object creation should happen elsewhere.


6. Some Benefits of Dependency Injection

Easier Code Maintainability: this means that code can easily be extended without having to modify all the codes.

Boiler-plate Code Reduction: so code to instantiate new  dependent objects are completed move away from the class.

Separation of Concerns: each code could concentrate on handling specific tasks

Easier Unit Testing: with DI, it is easier to test each component of the code. Mock objects could easily be used in place of other required code units.


Challenges of Dependency Injection

Learning Curve: It take some time to learn and master the concept of DI

Overuse: Dependency Injection would actually not be very useful for very small applications. So if overused could add unnecessary complexity to the codes

Runtime Errors: Errors that could have been trapped in compile time are shifted to run-time



Share this with friends