D
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.

Aspectget_it (Service Locator)Riverpod / BlocProvider
TypeService locator patternTree-based / provider-based DI
Context neededNoYes (BuildContext or ref)
TestinggetIt.reset(); re-register mocksOverride providers in test scope
Compile safetyRuntime errors if not registeredCompile-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