# Dependency Injection (DI)
**Dependency Injection (DI)** is a design pattern in which an object's dependencies are *supplied from the outside* rather than constructed internally. Instead of a class doing `this.db = new PostgresClient()`, the database client is passed in (via constructor, setter, or method parameter). The class declares what it needs; something external is responsible for assembling and providing it.
The term was popularized by [[Martin Fowler]] in his 2004 article *"Inversion of Control Containers and the Dependency Injection pattern"*, where he split the broader IoC family by giving the *injection*-style implementations a name of their own.
DI is a concrete *technique*. It's one of several ways to implement [[Inversion of Control (IoC)]], and one of several ways to satisfy the [[Dependency Inversion Principle (DIP)]] — but it is not the same as either.
## The three forms
| Form | Mechanism | Notes |
|------|-----------|-------|
| **Constructor injection** | Dependencies passed as constructor arguments | Default. Makes required collaborators explicit; objects are valid right after construction. |
| **Setter / property injection** | Dependencies assigned via setters or properties | Useful for optional dependencies; risks half-built objects. |
| **Method / parameter injection** | Dependencies passed per call | Right when the dependency is per-operation, not per-instance. |
## Why it matters
- **Testability**: dependencies can be swapped for fakes, mocks, or stubs without changing the class under test.
- **Configurability**: the same class behaves differently in dev, prod, and test by varying the wired-in collaborators.
- **Decoupling from construction**: the class doesn't need to know how its dependencies are built or where they come from. See [[Loose Coupling]].
- **Composition over hard-coding**: dependencies become part of the assembled graph. See [[Composition over Inheritance]].
## DI ≠ DI containers
DI is a *pattern* — passing dependencies from outside. A **DI container** (Spring, Angular's injector, NestJS's DI system, .NET's `IServiceCollection`, Guice, Dagger) is a *tool* that automates the wiring. You can do DI by hand with no container at all (and many codebases are healthier for it). You can also use a container in ways that defeat the point (singleton-everything, hidden global state, runtime-only resolution that hides errors).
The container is convenience; the pattern is the discipline.
## Pure DI (poor man's DI)
Manual constructor wiring at the [composition root](https://blog.ploeh.dk/2011/07/28/CompositionRoot/) — typically `main()` or the application entry point. No reflection, no annotations, no container. Easy to follow, easy to type-check, fast to start up. The right default for small/medium apps and libraries.
## DI vs IoC vs DIP
| | IoC | DIP | DI |
|---|---|---|---|
| **Type** | Principle (general) | Principle (specific) | Pattern / technique |
| **About** | Flow of *control* | Direction of *source-code dependencies* | *Mechanism* for supplying dependencies |
| **Scope** | The framework calls your code | Depend on abstractions, not concretions | Dependencies supplied from outside |
DI is the *how*. DIP is the *which way*. IoC is the *who's in charge*.
## Common pitfalls
- **Constructor over-injection**: 8+ dependencies in a constructor is a smell — the class is doing too much (violates [[SOLID Principles]] SRP).
- **Service Locator confused with DI**: pulling dependencies from a global locator inside the class is *not* DI; the dependencies are still hidden, just relocated. Caller can't tell what the class needs.
- **Field injection (annotations on private fields)**: hides dependencies from constructors, makes objects harder to instantiate in tests, breaks immutability.
- **Hidden runtime failures**: container-based wiring can defer "missing dependency" errors to startup or first request — pure DI surfaces them at compile time.
## References
- Martin Fowler — *Inversion of Control Containers and the Dependency Injection pattern* (2004) — https://martinfowler.com/articles/injection.html
- Mark Seemann — *Dependency Injection Principles, Practices, and Patterns* (Manning, 2019)
## Related
- [[Inversion of Control (IoC)]]
- [[Dependency Inversion Principle (DIP)]]
- [[SOLID Principles]]
- [[Loose Coupling]]
- [[High Cohesion]]
- [[Composition over Inheritance]]
- [[Test-Driven Development (TDD)]]
- [[Angular]]
- [[Martin Fowler]]