1 min read 292 words Updated Sep 24, 2026 Created Sep 24, 2026
#JavaScript#OOP#Programming#TypeScript#review

"Giving an object its instance variables" is a quote by James Shore to summarize DI.
Using DI, an object or function receives other object or functions it depends on instead of creating them internally. It leads to loosely coupled structure.


Example

Without DI:

class UserServiceWithoutDI {
	private logger: Logger;
	
	constructor() {
		this.logger = new Logger();
	}

	createUser(name: string): void {
		this.logger.log(`User created: ${name}`);
	}
}
// Usage
const userServiceWithoutDI = new UserServiceWithoutDI();

userServiceWithoutDI.createUser("Bob");

Using DI, loggerinstance is created outside and then passed:

class Logger {
	log(message: string): void {
		console.log(`Log: ${message}`);
	}
}  

class UserService {
	constructor(private logger: Logger) {}

	createUser(name: string): void {
		this.logger.log(`User created: ${name}`);
	}
}

const logger = new Logger();
const userService = new UserService(logger);

userService.createUser("Alice");

Why to use DI?

  • Testing is now way easier, as we can inject a mock instead of altering the UserService class with a mock
  • One can move the implementation details to the call-site. E. g. the Database Config Params are now in the entrypoint, e. g. the index.ts which reads from the ENV. The db.ts only receives the injected details
  • Implementation details, e. g. the logger itself can be changed without the class UserService must be changed. If we switched the logger, and now need parameters for verbose: false we just inject this detail. Without DI, we must alter the UserService itself
  • All imports for external dependencies can be run in the call-site. Especially in frontends, this can enable better lazy loading

DI and SOLID

Dependency Injection is not a part of SOLID. Yet, Dependency Inversion is a part, and Dependency Injection is a way of Dependency Inversion.

DI in languages & frameworks