Dependency Injection
Priority: P1 (HIGH)
Automated class dependency management using get_it and injectable.
Structure
core/injection/
├── injection.dart # Initialization & setup
└── modules/ # Third-party dependency modules (Dio, Storage)
Implementation Workflow
- Annotate classes — Use
@injectableannotations; avoid manual registry calls. - Choose scope — Default to
@LazySingletonfor repositories, services, and data sources (init on demand). - Register BLoCs as factories — Use
@injectable(Factory) for BLoCs to ensure state resets per instance. Never use@Singleton()for BLoCs. - Inject abstractions — Always register implementations as abstract interfaces (
as: IService). - Register third-party deps — Use
@modulefor external instances (Dio, Hive, SharedPreferences). - Prefer constructor injection — Use mandatory constructor parameters;
injectableresolves them automatically.
Registration & Test Mock Examples
See implementation examples for module registration and test mock swap patterns.
Reference & Examples
For module configuration and initialization templates: See references/REFERENCE.md.
Anti-Patterns
- ❌
getIt<OrderRepository>()inside widgetbuild()— inject via constructor, not GetIt calls in UI - ❌
@Singleton()on a BLoC — BLoCs must use@injectable(Factory) so state resets per instance - ❌ Injecting the concrete class:
OrderRepositoryImpl repo— always inject the abstract interface - ❌
getIt.registerLazySingleton<X>(() => X())in production code — use@injectableannotations; manual registration is only for tests
Related Topics
layer-based-clean-architecture | testing