Dependency Injection in JavaScript
Passing a component's dependencies in from outside rather than having it construct or reach out for them internally, improving testability and flexibility.
Dependency injection means a module receives what it needs instead of reaching for it.
Dependency injection is like a restaurant kitchen that receives ingredients delivered by whichever supplier the manager has currently arranged, rather than each individual chef personally growing their own vegetables and raising their own livestock in the back alley — swapping to a different, better supplier (or a test 'fake' supplier for a recipe rehearsal) never requires retraining the chef's actual cooking technique, since the chef only ever depends on 'whatever ingredients get handed to me,' not any one specific supplier.
Key Concepts
// reaching out -- hard to test
import { db } from './database.js';
export function getUser(id) { return db.query(...); } // injected -- easy
export function createUserService(db) {
return { getUser: (id) => db.query(...) };
} const service = createUserService({ query: () => fakeUser }); // wiring, in one place
const db = createDatabase(config);
const cache = createCache(config);
const userService = createUserService(db, cache);
const app = createApp(userService); export function createUserService(db = defaultDb) { } function isExpired(t, now = Date.now) { return t < now(); }