Files
agentic-dev-template/docs/decisions/adr-008-per-feature-di-containers.md

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_REPOSITORY symbol
  • 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