Flutter中GetIt包报错:Client类型对象/工厂未注册的解决求助
解决GetIt中Client未注册的_AssertionError错误
问题详情
在Flutter项目中使用GetIt管理依赖时,遇到如下_AssertionError错误:
'package:get_it/get_it_impl.dart': Failed assertion: line 372 pos 7:
'instanceFactory != null': Object/factory with type Client is not
registered inside GetIt. (Did you accidentally do GetIt
sl=GetIt.instance(); instead of GetIt sl=GetIt.instance; Did you
forget to register it?)
已在main函数中先await依赖初始化再运行应用,但错误仍存在。
项目依赖:
bloc: ^8.1.1 flutter_bloc: ^8.1.2 get_it: ^7.2.0
相关代码示例
main.dart
import 'package:bloc_app/theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'home_feature/home_screen.dart'; import 'home_feature/application/bloc/api_request_bloc.dart'; import 'package:bloc_app/injection.dart' as di; void main() async { WidgetsFlutterBinding.ensureInitialized(); await di.init(); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: AppTheme.ligthTheme, darkTheme: AppTheme.darkTheme, themeMode: ThemeMode.system, debugShowCheckedModeBanner: false, title: 'Flutter Demo', home: BlocProvider( create: (context) => di.sl<ApiRequestBloc>(), child: const MyHomePage(title: 'Bloc App'), ), ); } }
injection.dart
import 'package:bloc_app/home_feature/application/bloc/api_request_bloc.dart'; import 'package:bloc_app/home_feature/domain/repositories/advicer_repository.dart'; import 'package:bloc_app/home_feature/domain/usecases/advicer_usecases.dart'; import 'package:bloc_app/home_feature/infrastructure/datasources/advicer_remote_datasource.dart'; import 'package:bloc_app/home_feature/infrastructure/repositories/advicer_repository_impl.dart'; import 'package:get_it/get_it.dart'; import 'package:http/http.dart' as http; final sl = GetIt.instance; Future<void> init() async { // Blocs sl.registerFactory(() => ApiRequestBloc(usecases: sl())); //Usecases sl.registerLazySingleton(() => AdvicerUseCases(advicerRepository: sl())); //Repositories sl.registerLazySingleton<AdvicerRepository>( () => AdvicerRepositoryImpl(advicerRemoteDataSource: sl())); //Datasources sl.registerLazySingleton<AdvicerRemoteDataSource>( () => AdvicerRemoteDataSourceImpl(client: sl())); //Extern sl.registerLazySingleton(() => http.Client); }
api_request_bloc.dart
import 'package:bloc/bloc.dart'; import 'package:bloc_app/home_feature/domain/entities/advice_entity.dart'; import 'package:bloc_app/home_feature/domain/failures/failures.dart'; import 'package:bloc_app/home_feature/domain/usecases/advicer_usecases.dart'; import 'package:dartz/dartz.dart'; // ignore: depend_on_referenced_packages import 'package:meta/meta.dart'; part './api_request_event.dart'; part './api_request_state.dart'; class ApiRequestBloc extends Bloc<ApiRequestEvent, ApiRequestState> { final AdvicerUseCases usecases; ApiRequestBloc({required this.usecases}) : super(ApiRequestInitial()) { on<ApiRequestEvent>((event, emit) async { emit(ApiRequestLoading()); Either<AdviceEntity, Failure> adviceOrFailure = await usecases.getAdviceUsecase(); adviceOrFailure.fold( (advice) => emit(ApiRequestLoaded(advice: advice.advice)), (failure) => emit(ApiRequestError( error: _mapFailureToError(failure), )), ); }); } String _mapFailureToError(Failure failure) { switch (failure.runtimeType) { case ServerFailure: return 'Error: ${failure.runtimeType} ~ could not communicate with the server.'; case GeneralFailure: return 'Error: ${failure.runtimeType} ~ Could not define error.'; default: return 'Error: ${failure.runtimeType} ~ Could not define error.'; } } }
解决方案
1. 修复http.Client的注册错误
问题核心在于injection.dart中注册http.Client时,传递的是类本身而非实例。将:
sl.registerLazySingleton(() => http.Client);
修改为:
sl.registerLazySingleton(() => http.Client());
这样GetIt会注册http.Client的实例,而非类型本身。
2. 调整依赖注册顺序
为避免依赖顺序问题,将外部依赖的注册放在最前面,确保依赖它的组件注册时,依赖项已存在。修改后的init函数如下:
Future<void> init() async { // Extern - 先注册外部依赖 sl.registerLazySingleton(() => http.Client()); // Datasources sl.registerLazySingleton<AdvicerRemoteDataSource>( () => AdvicerRemoteDataSourceImpl(client: sl())); // Repositories sl.registerLazySingleton<AdvicerRepository>( () => AdvicerRepositoryImpl(advicerRemoteDataSource: sl())); // Usecases sl.registerLazySingleton(() => AdvicerUseCases(advicerRepository: sl())); // Blocs sl.registerFactory(() => ApiRequestBloc(usecases: sl())); }
3. 调试技巧
- 检查注册是否成功:在
init函数末尾添加print(sl.isRegistered<http.Client>()),确认Client已注册。 - 打印所有注册实例:使用
sl.allReady()配合debugPrint查看已注册的依赖,比如:await sl.allReady(); sl.debugPrint();
内容的提问来源于stack exchange,提问作者leonms
相关产品推荐
相关产品推荐

