Flutter Injectable环境配置失败:ConcreteTest未注册至GetIt
Injectable环境配置无法正常工作,依赖未注册错误
问题概述
刚接触Injectable包,很喜欢它,但无法使用环境配置功能。移除环境配置后一切正常,已经尝试解决三天却毫无进展,怀疑是包与新版本Flutter/Dart兼容问题,或者操作有误。
使用最新版本的injectable和get_it创建新Flutter项目时,出现以下错误:
$ flutter run [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: GetIt: Object/factory with type ConcreteTest 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?) #0 throwIfNot (package:get_it/get_it_impl.dart:12:19) #1 _GetItImplementation._findFactoryByNameAndType (package:get_it/get_it_impl.dart:396:5) #2 _GetItImplementation.get (package:get_it/get_it_impl.dart:424:29) #3 _GetItImplementation.call (package:get_it/get_it_impl.dart:464:12) #4 main (package:injectable_environments/main.dart:9:8) #5 _runMain.<anonymous closure> (dart:ui/hooks.dart:301:23) #6 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19) #7 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
复现步骤
- 使用
flutter create injectable_environments创建新Flutter项目 - 执行
flutter pub add injectable get_it添加依赖 - 执行
flutter pub add build_runner injectable_generator --dev添加开发依赖 - 使用以下代码
- 运行
dart run build_runner watch生成injectable.config.dart文件 - 最后运行
flutter run
代码文件
lib/main.dart
import 'package:flutter/material.dart'; import 'package:injectable_environments/concrete_test.dart'; import 'package:injectable_environments/injectable.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); configureDependencies(); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { getIt<ConcreteTest>(); return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ const Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.headlineMedium, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), ); } }
lib/test.dart
abstract class ITest { void pass(); }
lib/concrete_test.dart
import 'package:flutter/material.dart'; import 'package:injectable/injectable.dart'; import 'package:injectable_environments/test.dart'; @Injectable(as: ITest) @Environment("dev") // or @dev class ConcreteTest implements ITest { ConcreteTest(); @override void pass() { debugPrint("passed"); } }
lib/injectable.dart
import 'package:injectable_environments/injectable.config.dart'; import 'package:get_it/get_it.dart'; import 'package:injectable/injectable.dart'; final getIt = GetIt.instance; //Define the Environments here const dev = Environment('dev'); const prod = Environment('prod'); @InjectableInit( initializerName: r'$initGetIt', // default preferRelativeImports: true, // default asExtension: false, // default ) void configureDependencies({Environment environment = dev}) { //we init the dependencies using a specific env $initGetIt(getIt, environment: environment.name); }
Flutter环境
Flutter 3.16.1 • channel stable • https://github.com/flutter/flutter.git Framework • revision 7f20e5d18c (3 days ago) • 2023-11-27 09:47:30 -0800 Engine • revision 22b600f240 Tools • Dart 3.2.1 • DevTools 2.28.3
解决方案
问题核心是依赖注册与获取的类型不匹配,以及环境配置下的注册逻辑问题,修复步骤如下:
修正依赖获取逻辑
你用@Injectable(as: ITest)将ConcreteTest注册为ITest的实现,因此GetIt中仅注册了ITest类型,没有直接注册ConcreteTest。修改_MyHomePageState中的获取代码:// 替换原getIt<ConcreteTest>(); final test = getIt<ITest>(); test.pass(); // 可正常调用方法若需直接获取具体类的处理方式
如果你必须直接获取ConcreteTest,可选择以下两种方式:- 方式一:移除
as参数,直接注册具体类@Injectable() @Environment("dev") class ConcreteTest implements ITest { // ...原有代码 } - 方式二:同时注册抽象类与具体类
@Injectable(as: ITest) @Injectable() // 额外添加此注解注册具体类 @Environment("dev") class ConcreteTest implements ITest { // ...原有代码 }
- 方式一:移除
重新生成注册代码
修改注解后,运行dart run build_runner build更新injectable.config.dart,确保新的注册逻辑生效。
完成以上步骤后,依赖即可通过环境配置正常注册和获取,不再出现未注册错误。
内容的提问来源于stack exchange,提问作者Stalin Kay
相关产品推荐
相关产品推荐

