# ADR-0003: Dependency Injection Framework ## Status Accepted ## Context The platform requires dependency injection to: - Manage service lifecycle - Wire dependencies between components - Support module system initialization - Handle graceful shutdown - Provide testability through dependency substitution Options considered: 1. **uber-go/fx** - Runtime dependency injection with lifecycle management 2. **uber-go/dig** - Compile-time dependency injection 3. **Manual constructor injection** - No framework, explicit wiring ## Decision Use **uber-go/fx** (v1.23.0+) as the dependency injection framework. **Rationale:** - Provides lifecycle management (OnStart/OnStop hooks) crucial for services - Supports module-based architecture through fx.Option composition - Runtime dependency resolution with compile-time type safety - Excellent for modular monolith architecture - Well-documented and actively maintained - Used by major Go projects (Uber, etc.) ## Consequences ### Positive - Clean lifecycle management for services - Easy module composition via fx.Option - Graceful shutdown handling built-in - Test-friendly with fx.Options for test overrides ### Negative - Runtime reflection overhead (minimal) - Learning curve for developers unfamiliar with fx - Slightly more complex error messages on dependency resolution failures ### Implementation Notes - Install: `go get go.uber.org/fx@v1.23.0` - Create `internal/di/container.go` with fx.New() - Use fx.Provide() for service registration - Use fx.Invoke() for initialization tasks - Leverage fx.Lifecycle for service startup/shutdown