TypeScript Course
TypeScript
/
Advanced

Dependency Injection (DI)

Definition

A design pattern in which a class receives its dependencies from external sources rather than creating them itself.

Explain Like I'm New

Imagine a `Car` class. A bad Car builds its own engine inside its constructor (`this.engine = new V8Engine()`). Now that Car is permanently stuck with a V8 engine. Dependency Injection says: 'Don't build the engine. Ask for the engine in the constructor arguments.' (`constructor(engine: IEngine)`). Now you can easily pass in an ElectricEngine or a V8Engine.

Real World Example

Angular and NestJS are built entirely around DI. When you ask for a `DatabaseService` in a controller's constructor, the framework automatically finds it and injects it for you (Inversion of Control).

Common Use Cases

  • •Highly testable architectures
  • •Large scale frameworks (Angular/NestJS)

Interactive Example

// The interface contract
interface Logger {
  log(msg: string): void;
}

// Concrete dependencies
class ConsoleLogger implements Logger {
  log(msg: string) { console.log("[CONSOLE]: " + msg); }
}
class FileLogger implements Logger {
  log(msg: string) { /* writes to file */ }
}

// --- BAD WAY (Tightly Coupled) ---
class BadService {
  private logger = new ConsoleLogger(); // Hardcoded!
  doWork() { this.logger.log("Work done"); }
}

// --- GOOD WAY (Dependency Injection) ---
class GoodService {
  // It asks for ANY logger that matches the interface
  constructor(private logger: Logger) {}
  
  doWork() { this.logger.log("Work done"); }
}

// Now we control the dependencies from the outside!
const testService = new GoodService(new ConsoleLogger());
const prodService = new GoodService(new FileLogger());

Interview Questions

basic

  • What is a 'Dependency' in programming?

intermediate

  • How does DI make unit testing easier?

advanced

  • What is an IoC (Inversion of Control) Container?

Flash Cards

Question

How does DI make unit testing easier?

Click to reveal answer
Answer

If a `PaymentProcessor` creates its own `StripeAPI` inside it, you cannot test it without actually charging a credit card. If it uses DI (`constructor(api: IPaymentApi)`), you can pass a `MockPaymentApi` during tests that always returns 'Success' without hitting the internet.

Question

What is an IoC Container?

Click to reveal answer
Answer

It is a framework feature. Instead of you manually writing `new Engine()`, passing it to `new Car()`, and passing that to `new App()`, the IoC Container acts as a smart registry. You just say 'I need an App', and the container automatically builds the entire dependency tree and wires it together.