1.6 KiB
1.6 KiB
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:
- uber-go/fx - Runtime dependency injection with lifecycle management
- uber-go/dig - Compile-time dependency injection
- 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.gowith fx.New() - Use fx.Provide() for service registration
- Use fx.Invoke() for initialization tasks
- Leverage fx.Lifecycle for service startup/shutdown