Flutter中GetIt结合Floor初始化报错:factory未就绪
GetIt搭配Floor数据库初始化错误的问题解决
问题场景
在Flutter中使用GetIt库管理Floor数据库相关依赖时,执行await sl.init()后触发如下错误:
You tried to access an instance of UserDao that is not ready yet 'package:get_it/get_it_impl.dart': package:get_it/get_it_impl.dart:1 Failed assertion: line 404 pos 9: 'instanceFactory.isReady'
代码问题分析
错误根源在于UserDao的异步注册未正确声明依赖关系:
UserDao依赖异步初始化的AppDatabase,但原代码中使用registerLazySingletonAsync注册UserDao时,没有明确告知GetIt需要等待AppDatabase实例就绪后再创建UserDao。- GetIt在批量初始化异步实例时,会尝试并行处理所有注册项,导致
UserDao的创建逻辑提前执行,此时AppDatabase尚未完成初始化,进而触发未就绪断言错误。
修复方案
方案一:通过dependsOn声明依赖关系
在注册UserDao时,添加dependsOn参数指定依赖AppDatabase,让GetIt确保依赖实例就绪后再初始化当前实例:
final sl = GetIt.instance; Future<void> init() async { /// 注册Floor数据库实例 sl.registerLazySingletonAsync<AppDatabase>( () => $FloorAppDatabase.databaseBuilder('app_database.db').build()); /// 注册Http客户端 sl.registerLazySingleton<ApiService>( () => NetworkModule().getHttpProvider().getService()); /// 注册UserDao,声明依赖AppDatabase sl.registerLazySingletonAsync<UserDao>( () async => (await sl.getAsync<AppDatabase>()).userDao, dependsOn: [AppDatabase]); }
方案二:先同步初始化数据库再注册依赖
先完成AppDatabase的异步初始化,再将其注册为同步单例,后续UserDao直接依赖已就绪的数据库实例:
final sl = GetIt.instance; Future<void> init() async { /// 先完成数据库实例初始化 final appDb = await $FloorAppDatabase.databaseBuilder('app_database.db').build(); sl.registerLazySingleton<AppDatabase>(() => appDb); /// 注册Http客户端 sl.registerLazySingleton<ApiService>( () => NetworkModule().getHttpProvider().getService()); /// 直接使用已就绪的数据库实例注册UserDao sl.registerLazySingleton<UserDao>(() => appDb.userDao); }
方案说明
- 方案一保留了异步注册的模式,通过显式声明依赖关系,让GetIt处理异步实例的初始化顺序,适合需要延迟初始化的场景。
- 方案二通过提前完成数据库初始化,将异步依赖转为同步依赖,逻辑更直观,避免了异步时序问题,适合启动时需要立即就绪数据库的场景。
内容的提问来源于stack exchange,提问作者Surya Adiputra
相关产品推荐
相关产品推荐

