Skip to main content

Command Palette

Search for a command to run...

Wtf is dependency injection? (JavaScript edition)

You might be using it already.

Updated
3 min read
Wtf is dependency injection? (JavaScript edition)
T

Just a guy who loves to write code and watch anime.

Introduction

Dependency injection.

You might be using it already.

It’s straightforward and a nice way to give more control to the consumers of the functions or classes.

Let’s take a look at an example. I’ll use both classes and functions in JavaScript.

The problematic path

Let’s say we’ve a function that always does smoothies.

So far, it’s always done them using bananas and strawberries.

// Using functions

function makeSmoothie() {
  let banana = getBanana();
  let strawberry = getStrawberry();
  // ...blend it all together...
  return `${banana} and ${strawberry} smoothie! Yum!`;
}

function getBanana() {
  // Imagine this function goes out to a Banana farm and gets a banana
  return 'banana';
}

function getStrawberry() {
  // This function, on the other hand, visits a berry patch.
  return 'strawberry';
}
// Using classes

class SmoothieMaker {
  constructor() {
    this.banana = this.getBanana();
    this.strawberry = this.getStrawberry();
  }

  getBanana() {
    // Gets banana from a specific source
    return 'banana';
  }

  getStrawberry() {
    // Gets strawberry from a specific source
    return 'strawberry';
  }

  makeSmoothie() {
    return `${this.banana} and ${this.strawberry} smoothie! Yum!`;
  }
}

const mySmoothieMaker = new SmoothieMaker();
console.log(mySmoothieMaker.makeSmoothie()); // Outputs: banana and strawberry smoothie! Yum!

The problems

The above examples may seem silly, but imagine we're working in a large codebase.

The functions and classes are larger. They're used in multiple places.

We have several issues here:

  • Hard to maintain: The code isn't flexible. Imagine we want to create smoothies using other ingredients. It's gonna be painful.

  • Hard to test: Let's imagine for a second getBanana function is an async function that fetches a specific type of banana. In our tests, it'd be easier to mock the getBanana function. But now we have no ability to do so.

Dependency injection to the rescue

Here is the code after dependency injection:

// Using functions

function makeSmoothie(fruit1, fruit2) {
  // ...blend it all together...
  return `${fruit1} and ${fruit2} smoothie! Yum!`;
}

const banana = getBanana();
const strawberry = getStrawberry();
console.log(makeSmoothie(banana, strawberry)); // Banana and strawberry smoothie! Yum!
// Using classes

// Define functions for fetching ingredients
function getMango() {
  return 'mango';
}

function getPineapple() {
  return 'pineapple';
}

// The SmoothieMaker now expects two functions as its dependencies
class SmoothieMaker {
  constructor(getFruit1, getFruit2) {
    this.getFruit1 = getFruit1;
    this.getFruit2 = getFruit2;
  }

  makeSmoothie() {
    let fruit1 = this.getFruit1();
    let fruit2 = this.getFruit2();
    return `${fruit1} and ${fruit2} smoothie! Yum!`;
  }
}

// When creating a new SmoothieMaker, we inject the functions directly
const mySmoothieMaker = new SmoothieMaker(getMango, getPineapple);
console.log(mySmoothieMaker.makeSmoothie()); // Outputs: mango and pineapple smoothie! Yum!

Now, the code is much more flexible.

This is easier to maintain, test and use.

Conclusion

Dependency injection may be a fancy word.

But we use this pattern all the time.

S

you made it simple AF!!

W

Unlike what others may have mentioned, Dependency Injection is a method that enables you to supply an object from your app's root, making it accessible anywhere you need it in your app. Before this, we had to pass items like Props from the root down through each level of children, which could be cumbersome. With DI, you simply pass the Prop or Object to the Provider, assigning it a name. Later, if you're several levels down and need something from the Provider, you just call Inject with the designated name, and there you have it. This mechanism is incredibly useful. Vue.js has a great implementation of this, and it's common in other modern systems too.

S

OKVIP không chỉ là một trang liên minh với các nhà cái uy tín hàng đầu thế giới trong lĩnh vực game online, mà còn là một nơi đầy tâm huyết, đã nắm bắt tầm quan trọng của trách nhiệm xã hội https://okvip.site/trang-jun88/ https://okvip.site/cac-hoat-dong-tu-thien/ https://okvip.site/nha-cai-f8bet/ https://okvip.site/nha-cai-789bet/ https://okvip.site/nhan-su/ https://okvip.site/thiet-ke-hinh-anh/

K

Contrary to what others have said, Dependency Injection is a mechanism that allows you to Provide an object from the root of your app, and then you can Inject it anywhere in your app that you need. Without this, we had to pass things like Props from the root, to its children, then to those children's children, etc., until the Prop arrived at the place where we wanted to use it. With DI, you just pass the Prop, Object, or whatever to the Provider, giving it a name string. Then, let's say you are 5 levels down in your component hierarchy, and you want one of the things you gave to the Provider. You just call Inject, giving it the name of the thing you want, and there it is. This mechanism is VERY handy. Vue.js provided a great implementation of this, but so do most other modern systems.

1
B

In Android dependency injection is a scam employed to sell more development hours. Why do manual dependency injection especially in a language that has lazy and lateinit, when you can employ a framework not tailored to your needs and fight with it and bill more hours. I am not a js developer but it seems you are advocating manual dependency injection that i also rezonate with