4 ms·
Going to steal a description I wrote for a blogpost several years ago, when I had recently understood DI for the first time so it was very fresh in my mind: ht
by gavinray 4y ago
Going to steal a description I wrote for a blogpost several years ago, when I had recently understood DI for the first time so it was very fresh in my mind:
https://hasura.io/blog/build-fullstack-apps-nestjs-hasura-graphql-api/#dependency-injection-di https://hasura.io/blog/build-fullstack-apps-nestjs-hasura-gr...
Dependency Injection solves the problem of when you want to create something, but THAT something also needs OTHER somethings, and so on.
In this example, think about a car.
A car might have many separate parts it needs:
class Car {
constructor(wheels: Wheels) {}
}
class Wheels {
constructor(tires: Tires) {}
}
class Tires {
constructor(rims: Rims, treads: Treads)
}
class Rims {
constructor() {}
}
class Treads {
constructor() {}
}
We can manually construct a car, like:
const car = new Car(new Wheels(new Tires(new Rims(), new Treads())))
But this is tedious and fragile, and it makes it hard to be modular.
With dependency injection, it allows you to register a sort of "automatic" system for constructing an instance of "new Foo()", that continues down the chain and fetches each piece.
class NeedsACar {
constructor(@Inject private car: Car) {}
}
And then "class Car" would have an "@Inject" in it's "constructor", and so on down the chain.
When you write tests, you can swap out which instance of the "@Injected" class is provided (the "Dependency") much easier.
- TillE 4y agoI know the car is a classic, cliche OOP example, but for any semi-experienced programmer, I feel like it's a really bad choice of analogy which only serves to obscure how you would use a technique like DI in actual real-world code, rather than an artificial toy example.
- jacobsimon 4y agoI think you might have it backwards. The first example _is_ dependency injection, too, since you are passing the required instances into the constructor. The non-DI approach would be for the Car class to import and instantiate the Wheels class inside its constructor function.
- sanderjd 4y agoThe first example is also dependency injection. The rest of what you described is why a dependency injection framework often becomes useful in a system with a large dependency tree. The alternative to dependency injection is for functions to instantiate dependencies internally rather than having them be passed in from the calling context.
- lamontcg 4y agoI'd probably reach for a Builder pattern first for that rather than go full DI container.