Dependency Injection: The Core

Knoldus Inc.
Knoldus - Technical Insights
4 min readAug 17, 2018

We can define Dependency Injection as a technique where one object supplies the dependencies to other objects. But what actually does it mean?
Well, there are many answers to this question and sometimes they are quite confusing and annoying. But in this blog, I’ll try to keep things quite straightforward and as simple as possible.

A class has a dependency on another class if it uses an instance of this class. We call this a dependency. Ideally, classes should be as independent as possible from other classes. This increases the possibility of re-usability of these classes and to be able to test them independently from other classes.

DgRbnNRUcAAaBTW

Terminologies:

Dependency :
Dependency here simply means an object that can be used as a service to another object. Here services are nothing but the methods provided by that object.

Injection :
Injection is the passing of this very object(dependency) to its dependent object which is going to use its services.

So far so good. I hope now you guys have a basic idea of these two terminologies.

Image result for problem statement

Problem Statement:

Let’s first start with the problem, i.e., what’s the situation where we felt the need for dependency injection.

[code language = “javaScript”]case class Service(service: String)

class Customer {
// dependency
val service = Service(“service 1”)

def getService: Service = service
}

object Application extends App {
val customer1 = new Customer
val customer2 = new Customer
customer1.getService
customer2.getService
}[/code]

So, what’s the problem in the above code?

Yes, you got it right!!! In the above code, class Customer is tightly coupled with Service class. So, whenever we create a new Customer, we are unable to create a different Service for the new Customer. For achieving it, we have to create as many numbers of Service objects inside Customer and it’s related methods, but that’s doesn’t make any sense at all. Here comes the concept of Dependency Injection.

The general concept behind dependency injection is called Inversion of Control. According to this concept, a class should configure its dependencies from outside. The intent behind Dependency Injection is to decouple objects.

Image result for solution

Solution:

[code language = “javaScript”]case class Service(service: String)

class Customer(service: Service) {

def getService: Service = service

}

object Application extends App {
val customer1 = new Customer(Service(“service 1”))
val customer2 = new Customer(Service(“service 2”))
customer1.getService
customer2.getService
}[/code]

There are the various techniques to achieve Dependency Injection like Constructor Injection, Cake Pattern, Google Juice, etc. But that’s an entirely different topic which I will be leaving for another day. We’re currently here to deal with its core concept. The above-used Dependency Injection technique is popularly known as Constructor Injection.

Advantages:

  1. Decreases coupling between a class and its dependency.
    Dependency injection makes it possible to eliminate, or at least reduce, a components unnecessary dependencies. A component is vulnerable to change in its dependencies.
  2. Less BoilerPlate Code:
    Reduces the boilerplate code.
  3. Effective Unit tests :
    Helps in writing Unit tests more easily and efficiently.
  4. Increase code re-usability :
    Reducing a component’s dependencies typically makes it easier to reuse in a different context. The fact that dependencies can be injected and therefore configured externally, increases the re-usability of that component.
  5. More readable code :
    Dependency injection moves the dependencies to the interface of components. This makes it easier to see what dependencies a component has, making the code more readable. You don’t have to look through all the code to see what dependencies you need to satisfy for a given component. They are all visible in the interface.
  6. More testable code :
    Dependency injection also increases a components testability. When dependencies can be injected into a component it is possible to inject mock implementations of these dependencies.
  7. Reduced Dependency Carrying :
    A component A boots an application and creates a configuration object, Config, that is needed by some but not all of the components in the system. Then A calls B, B calls C and C calls D. Neither B or C needs the Config object, but D does. Here is the call chain
  • A creates Config
    A → B → C → D → Config
  1. When you use a dependency injection container you can reduce dependency carrying, as you can pass A in B and A itself contains config and hence ultimately reaches D.

And many more…

Conclusion:

Dependency Injection is nothing but a logical way to reduce coupling among the objects, which ultimately helps in writing clean, maintainable and testable code.

I hope you now have a logical understanding regarding the dependency injection.

Please do provide your valuable comments and suggestions.

knoldus-advt-sticker

--

--

Knoldus Inc.
Knoldus - Technical Insights

Group of smart Engineers with a Product mindset who partner with your business to drive competitive advantage | www.knoldus.com