Understanding Dependency Injection in JavaScript
Tags: javascript, webdev, programming, beginners
Published: 2021-12-06 06:02:32

Dependency Injection is a fairly complex topic for beginners. It might not be necessary to know the concept but knowing it will help you make better decisions on your code.

Lets start by the definition. 
Dependency Injection - Dependency Injection is the technique in which an object receives other object in which it depends on (source: Wikipedia). 

Now lets try to break down the definition a bit. Lets start by object. An object is an instance of a class. For Example
```js
// lets define a class dog
class Dog{
  speak(){
    console.log("wuff");
  }
}

//now lets create object dog
const fluffy = new Dog();
```
In the above example, we have a class Dog and fluffy is the object of the class Dog. When we new up a class we create an object of that class. This is one of the ways of creating an object in Javascript (and its the common way to create an object in languages like c# and java). 
Lets now see an example where 2 objects are dependent on each other.
```js
class Pet{
  whatDoesMyPetSay(){
    const pet = new Dog();
    pet.speak();
  }
}

const fluffy = new Pet();
fluffy.whatDoesMyPetSay();
// response will be "wuff"
```
Here, as we see, the class Pet is dependent on class Dog. So to get what we want, we need to create an instance of Dog inside our Pet class. Now this class is not reusable as it is tied to Dog class. If someone has a cat as Pet, they wont be able to use this class. This is what is called as tightly coupled code.
Now lets change this code and try to satisfy all other pet owners with dependency Injection. But first, lets create a cat class
```js
class Cat{
  speak(){
    console.log("meow");
  }
}
```
The cat class must also implement the same method for Dependency Injection to work. In languages like C# and Java this is ensured by using an interface. But we have no such method in JavaScript, so it is up to the developer to remember it. Now lets see the new implementation of the pet class.
```js
class Pet{
  //usually we have a private variable that needs 
  //to be accessed only in this class
  #pet;

  //create a constructor that recieves the dependent
  //object
  constructor(pet){
    this.#pet = pet;
  }

  whatDoesMyPetSay(){
    //as long as pet class implements speak method we are fine
    this.#pet.speak();
  }
}

//what does fluffy the dog say?
const fluffy = new Pet(new Dog());
fluffy.whatDoesMyPetSay();
//The response will be "wuff"

//what does milo the cat say?
const milo = new Pet(new Cat());
milo.whatDoesMyPetSay();
//The response will be "meow"
```

Now, we have removed the dependency from inside the pet class and have given it to the caller of the class. This promotes the reusability of the pet class. This is a very simple example and the purpose is to only understand dependency injection and not to implement it. In real world, the dependency is abstracted even from the caller and given to a new object, which is usually called an Injector.

## Why not to use Dependency Injection in JavaScript
If you have read till here I hope you are clearer with the concept of dependency injection. Now lets see some reasons we might not want to use dependency injection
- Unlike purely class based languages like c# and java, JavaScript provides us lots of flexibility when it comes to grouping functionalities. Many times, you won't even need to use a class and just using a function might be enough. In those cases, trying to implement Dependency injection will only create unnecessary complexities.
- JavaScript also happens to be dynamic in nature. You can overwrite and use any function implementation in JavaScript. So we should make use of these rather then dependency injection for unit testing our code.

At the end of the day, as a developer, we should realize that there is no one solution that fits all problems. I hope with this article, you would be able to take a better decision on your solutions.