Understanding Dependency Injection (DI)


This post is also available in: Español

In object-oriented programming (OOP) you can think of objects or classes as components or modules that work together to provide the program’s functionality. In a well-structured program, you may want to replace Module A with Module B and even add new components to Module B, you may want to add unit testing or refactoring of legacy code. To accomplish this easily, you want to develop components that are loosely decoupled from each other, loosely decoupled means independent from each other.

Dependency Injection is a technique for developing software components that are loosely coupled from their dependencies.

To better understand the concept of DI, I won’t use Dependency Injection containers like: Spring, Google Guice, Dagger for Android, Ninject for .NET, etc., but these frameworks are extremly helpful if working on big projects.

DI is a type of Inversion of Control (IoC) and a pattern used in almost all programming languages

There are three most common forms of Dependency Injection

  1. Constructor Injection
  2. Setter Injection
  3. Interface Injection

Constructor Injection
The dependency is passed as an argument to the constructor

Setter Injection
The dependency is passed as an argument to a method, this is also called property injection or field injection

Interface Injection
Dependent classes implement an interface

Let’s have a look at the following program in Java:

Ferrari.java

Driver.java

Output: I drive a Ferrari

In this example, the Driver class is tightly coupled to its dependency (Ferrari), if the driver had to drive a Porsche, we would have to refactor the Driver class.

Let’s decouple the class Driver from the class Ferrari in such a way that the class Driver can drive any car he wants.

Constructor Injection

In a first step, we define an interface Car

Car.java

Now the class Ferrari implements the interface Car

Ferrari.java

Let us create another class of type Car

Porsche.java

Now we refactor the Driver class so that an instance of Car is passed as an argument to the constructor, then set the dependency to a local private field and use it everywhere within the class.

Driver.java

Output:
I drive a Ferrari
I drive a Porsche

Setter Injection

In this approach we provide a setter method (setCar) that injects the dependency. Basically the same as before, but using a setter method instead of the constructor.

Driver.java

Output:
I drive a Ferrari
I drive a Porsche

Interface Injection

Each class that uses the dependency must implement an interface, in this case CarSetter, which provides a method for injecting the dependency on which it depends.

Driver.java

Leave a Reply

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

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">