Dependency Injection

Hasini Senanayaka
3 min readJan 24, 2021

Dependency Injection (DI) is a design pattern used to implement Inverse of Control. It let user to create dependent objects outside of a class and supplies those objects to a class by different type of ways. In DI, creation and binding of the dependent objects has been moved out outside of the class that uses those dependent objects. There are 2 things in dependency injection. First is dependency. Other one is injection.

First lets talk about dependency. Suppose there are 2 classes called App and EmailService. They have to be connected to send a message.

class App{
public void processMsg(String receiver, String msg){
//service has to be used to send data.
}
}

App class want to use some kind of message service to process the message. So Let’s create Email Service.

class EmailService{
public void sendMSg(String receiver, String msg){
System.out.println("Message send using Email Service");
}
}

Direct way to connect these two is creating instance of EmailService.

class App{
Email Service es = new EmailService();
public void processMsg(String receiver, String msg){
es.sendMsg(receiver, msg);
}
}

Now App uses some features in the EmailService class to make its work done. So we can say App depends on EmailService. In other words EmailService is a dependency of App.

This implementation is not good because of following reasons.

  • We talk about P2I(program to interface). Here EmailService is a concrete class.
  • We exactly don’t know weather messages are sent only using email. There may be another methods like smsService. If it is so whole EmailService class instance has to be removed. It violates the rule, open for extension close for modification.
  • When ever you use “new” keyword our program become tightly coupled.
  • Testing becomes difficult. Because inside processMsg() method service instance is used which has been created inside same class as processMsg().

For the problems first and second let’s modify EmailService like below.

Interface MessageService{
public void sendMsg(String receiver, String msg);
}
class EmailService implements MessageService{

@override
public void sendMSg(String receiver, String msg){
System.out.println("Message send using Email Service");
}
}
class SmsService implements MessageService{

@override
public void sendMSg(String receiver, String msg){
System.out.println("Message send using SMS Service");
}
}

Now let’s go for third and fourth questions. Answer to these questions is Dependency Injection. There 3 types of Injections.

  1. Constructor based
class App{
MessageService service;

App(MessageService service){
this.service = service;
}
public void processMsg(String receiver, String msg){
service.sendMsg(receiver, msg);
}
}

So when calling App class we have to add which service we have to use.

App app = new App(new EmailService());ORApp app = new App(new SmsService());

Even though App class has dependency on EmailService, they are not highly coupled.

2.Setter based(method based)

New method called setService() is used to inject service object.

class App{
MessageService service;

App(){
}
public void setService(MessageService service){
this.service = service;
}
public void processMsg(String receiver, String msg){
service.sendMsg(receiver, msg);
}
}

When calling App class we have to call setService() method and add which service we are going to use.

App app = new App();
app.setService(new EmailService());
ORApp app = new App();
app.setService(new SmsService());

3. Property based

class App{
@AutoWired
MessageService service;
public void processMsg(String receiver, String msg){
service.sendMsg(receiver, msg);
}
}

When we call App app = new App(), App class automatically injects instance of MessageService.

So hope you got understanding about what dependency injection is. Simply Dependency injections is when you have something setting the dependencies for you. This something is usually a framework.

--

--