The following code is part of a tutorial about Bloc:
service_locator.dart
final getIt = GetIt.instance;
void serviceLocatorInit() {
getIt
..registerSingleton(UsernameCubit())
..registerSingleton(RouterSimpleCubit())
..registerSingleton(CounterCubit())
..registerSingleton(ThemeCubit())
..registerSingleton(GuestsBloc())
..registerSingleton(PokemonCubit())
..registerSingleton(HistoricLocationBloc())
..registerSingleton(
GeolocationCubit(getIt<HistoricLocationBloc>().onNewUserLocation)..watchUserLocation()
)
;
}
main.dart
void main() {
serviceLocatorInit();
runApp(const BlocsProviders());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
final appRouter = context.read<RouterSimpleCubit>().state;
final theme = context.watch<ThemeCubit>().state;
return MaterialApp.router(
title: 'Welcome to Flutter',
debugShowCheckedModeBanner: false,
theme: AppTheme(isDarkmode: theme.isDarkMode).getTheme(),
routerConfig: appRouter,
);
}
}
class BlocsProviders extends StatelessWidget {
const BlocsProviders({super.key});
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (_) => getIt<UsernameCubit>()),
BlocProvider(create: (_) => getIt<RouterSimpleCubit>()),
BlocProvider(create: (_) => getIt<CounterCubit>()),
BlocProvider(create: (_) => getIt<ThemeCubit>()),
BlocProvider(create: (_) => getIt<GuestsBloc>()),
BlocProvider(create: (_) => getIt<PokemonCubit>()),
BlocProvider(create: (_) => getIt<GeolocationCubit>()),
BlocProvider(create: (_) => getIt<HistoricLocationBloc>()),
],
child: const MyApp(),
);
}
}
I have this question: is there some relevant use for get_it
package in this code? because the author uses context.read
or BlocBuilder
for the rest of tutorial and in my opinion that makes irrelevant the use of get_it
since BlocProvider already injects Bloc objects.
You're totally right! The creator of the flutter_bloc
package himself advised against using get_it
to provide the instance of a Bloc or Cubit to a BlocProvider
because it's already doing all the work of injecting your bloc:
[...] I recommend not mixing BlocProvider with get_it but the immediate fix would be to change the bloc/cubit registrations to be factories instead of lazy singletons.
Felix Angelov, Jan 19, 2022
The point of using a service locator is to simplify the replacement of an instance (often for testing) BlocProvider
is already enough because you can already easily override the instance of a Bloc/Cubit you're refering to by wrapping your widget inside a new BlocProvider
/MultiBlocProvider
.
Personally, I use get_it
to handle the injection of my repositories, use cases and datasources, but using it to inject the instance provided by a BlocProvider
is just overkill and might even cause some weird behavior in some cases.