Comparison
When should you use a Python DI container?
Injex is for shared service graphs across APIs, CLIs, workers, and tests. It is not meant to replace every Python dependency style.
| Need | Good fit | Why |
|---|---|---|
| A few dependencies in one entrypoint | Manual wiring | Direct constructor calls stay clearest. |
| Request dependencies inside one framework | Framework DI | The framework already owns the request lifecycle. |
| Shared service graph across API, CLI, worker, and tests | Injex | One composition root avoids repeated setup code. |
| Typed constructor injection without provider DSL | Injex | Normal Python annotations become the wiring contract. |
| Complex provider/configuration framework | Larger DI container | Use a heavier tool when a rich DSL is the product need. |
What Injex optimizes for
- Small API surface that is easy to read in application startup.
- Constructor injection from existing type hints.
- Explicit test overrides instead of global monkeypatching.
- Graph validation before real services are constructed.
What it intentionally avoids
- Runtime dependencies.
- Large provider/configuration DSLs.
- Framework-specific core APIs.
- Required decorators for normal constructor injection.
Short answer: if manual wiring is still obvious, keep it. If the same graph is repeated across entrypoints and tests, Injex starts to pay for itself.