You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:05:19