State ManagementIntermediate30 XP3 min read
How does dependency injection work in Flutter state management?
TL;DR: Flutter apps commonly use get_it (service locator), BlocProvider/RepositoryProvider (tree-scoped DI), or Riverpod (compile-safe global providers) to inject dependencies like repositories and services.
Full Answer
Dependency injection decouples construction from usage. In Flutter, this is critical for testability โ you swap real implementations with mocks in tests.
| Aspect | get_it (Service Locator) | Riverpod / BlocProvider |
|---|---|---|
| Type | Service locator pattern | Tree-based / provider-based DI |
| Context needed | No | Yes (BuildContext or ref) |
| Testing | getIt.reset(); re-register mocks | Override providers in test scope |
| Compile safety | Runtime errors if not registered | Compile-time (Riverpod) |
๐ฏ
get_it pairs well with BLoC: register repositories in get_it, inject them via RepositoryProvider, and use BlocProvider with the injected repository.
Code Examples
dartget_it service registration
Output
UserBloc gets UserRepository injected; UserRepository gets ApiClient injected; all via the service locator
Common Mistakes
- โUsing get_it.registerSingleton for classes that should be per-instance โ use registerFactory
- โNot resetting getIt in tests โ previous test registrations pollute later tests
Interview Tip
๐ก
Show you understand the tradeoff: get_it is simpler but less safe than compile-time DI. This signals architectural maturity.
#dependency-injection#get_it#Riverpod#BlocProvider#DI