Dependency Injection — Notes
When DI pays off
- Testing — swap real for fake / mock.
- Multiple deployments — same code, different config (cloud A vs B).
- Plug-in architectures — load implementations at startup.
- Cross-cutting concerns — inject logging / metrics / tracing.
When it's overkill
- Trivial CLI tools.
- Pure functions without external state.
Useful rules
- Constructor injection by default.
- Don't pass the container around; pass the things.
- One composition root.
- Avoid runtime reflection magic when compile-time injection works (Dagger > Spring runtime for performance).
- Lifecycle scopes match logical boundaries (request, transaction, batch).
DI vs IoC
- Inversion of Control (IoC): a framework calls you, you don't call the framework.
- Dependency Injection: a specific IoC technique focusing on how dependencies arrive.
- All DI is IoC; not all IoC is DI (e.g. event loops are IoC without DI).
Refs
- Martin Fowler: "Inversion of Control Containers and the Dependency Injection pattern" (2004).
- Mark Seemann: Dependency Injection in .NET (book, but principles are language-agnostic).
- Google Dagger user guide (compile-time DI).