News for hackers. Stuff that matters.
Re:Ask HN: Concepts that clicked only years after you first ... by gavinray on Sunday January 01, 2023 @10:26AM (#34207019)
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-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.

Re:Ask HN: Concepts that clicked only years after you first ... by TillE on Sunday January 01, 2023 @10:37AM (#34207111)
I 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.
Re:Ask HN: Concepts that clicked only years after you first ... by jacobsimon on Sunday January 01, 2023 @11:09AM (#34207451)
I 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.
Re:Ask HN: Concepts that clicked only years after you first ... by sanderjd on Sunday January 01, 2023 @11:43AM (#34207852)
The 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.

Re:Ask HN: Concepts that clicked only years after you first ... by lamontcg on Sunday January 01, 2023 @02:12PM (#34209644)
I'd probably reach for a Builder pattern first for that rather than go full DI container.