1.4 KiB
1.4 KiB
ADR-008: Per-Feature InversifyJS Containers
Status: Accepted Date: 2026-05-04
Context
The original template used a single shared InversifyJS Container in packages/core/src/di/. As the number of features grows, the container becomes a point of coordination: adding a symbol requires modifying shared code, and tests that mock one feature risk breaking others.
Decision
Each feature owns its own Container and symbol table. No shared DI state. Tests rebind per feature in isolation. Apps boot by calling bindProduction*() for each feature independently.
Example:
// packages/blog/src/di/container.ts
export const container = createContainer();
// packages/blog/tests/feature.test.ts
beforeEach(() => {
rebindRepository(new TestRepository());
// Only blog's container is affected
});
Consequences
- Zero cross-feature DI coupling — each feature's test can mock its repos without coordination
- Symbol collisions impossible — each feature has its own
ARTICLES_REPOSITORYsymbol - Shared services (if needed) are explicitly bound in each feature that uses them
- Apps must boot each feature's container on startup
Alternatives Considered
- Single shared container: Simpler upfront, becomes a bottleneck and test coordination point
- Function injection (no DI): Avoids framework overhead, but loses the scaling benefits of DI