# 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]]