TT Lab
Get started
Learn Learning paths Courses

Node.js Backend — What the Framework Hides

Dependency Injection — What It Means to Take It as an Argument

Continue in TT Lab

In one line

Dependency injection is not a difficult concept; it means receiving things as arguments. If you pass in from outside instead of referring to a global directly, you can pass in something else when testing.

Why it is needed: not for the sake of tests

If you learn DI as "something you use because of testing," the purpose is off. The real reason is marking in the code the places where things can be swapped.

Say you move the repository from PostgreSQL to the front of a Redis cache. If a handler calls db.query(...) directly, you have to fix every handler. If the repository is received as an argument, only the side that passes it in changes. Testability is a byproduct of that property.

Building it by hand

export function createApp({ store }) {
  return async function handle(req) { /* store 를 쓴다 */ };
}

All a framework does is find this { store } automatically and pass it in. Nest's providers and Spring's Beans are that automation. If you do not know what the automation hides, you will not know where to look when injection fails.

In the field

When you are asked "why do you use DI?" in an interview, the answer is usually "because it makes testing easy." It is not a wrong answer, but it is half of one. The purpose is to invert the direction of dependencies so that a higher-level module is not tied to the implementation of a lower-level module, and testability is the result.

And the place where DI falls apart in practice is always the same: the moment someone imports one global singleton directly because it is "convenient." From then on, that module can no longer be swapped out.