Flutter GetIt 抛出实例异常

问题描述 投票:0回答:2

我正在尝试使用

get_it
在我的 flutter 应用程序中注册我的服务,并且需要在开始时通过异步调用初始化一个依赖项。 正如我在官方 Get_It pub 页面上读到的那样,这应该不是问题,只要我为依赖于该可初始化类的依赖项定义 dependentOn 属性。

在我的示例中,

DeviceInfo
是需要初始化的类,
Gateway
WorkingTimeRepository
都依赖于该类。两者都定义了它们的 dependentOn 属性。

void setup() {
  getIt.registerSingletonAsync<DeviceInfo>(() async => DeviceInfo.init());

  getIt.registerSingletonWithDependencies(
      () => Gateway(deviceInfo: getIt.get()),
      dependsOn: [DeviceInfo]);

  getIt.registerSingletonWithDependencies<WorkingTimeRepository>(
      () => WorkingTimeRepository(
          dio: new Dio(), httpHeader: new HttpHeader(), gateway: getIt.get()),
      dependsOn: [DeviceInfo, Gateway]);
}

现在,当我的应用程序启动并且我的第一个小部件想要访问WorkingTimeRepository时,我立即得到一个异常:

════════小部件库捕获异常═════════════════════════════ ══════ 构建 MainView 时抛出以下断言: 您尝试访问尚未准备就绪的WorkingTimeRepository 实例 '包:get_it/get_it_impl.dart': 断言失败:第 322 行 pos 14:'instanceFactory.isReady'

我找不到我犯的错误,而且我认为在访问注册类型时,它会解决所有依赖关系

有人知道这里缺少什么吗?

flutter dart dependency-injection
2个回答
6
投票

使用异步依赖项时,您需要等到所有依赖项创建完毕才能启动应用程序。实现此目的的一种方法是向 MaterialApp 添加一个 TransitionBuilder,并使用一个侦听 getIt.allReady() 的 FutureBuilder。

示例:

return MaterialApp(
  builder: (context, widget) {
    return FutureBuilder(
        future: getIt.allReady(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData) {
            return widget;
          } else {
            return Container(color: Colors.white);
          }
        });
  },
);

0
投票

问题:您尝试访问尚未准备就绪的 SharedPrefsService 实例。

如果您正在初始化任何

await
或任何需要时间的功能。使用

注册SingletonAsync

而不是

注册LazySingletonAsync

在顶部,因为如果任何其他单例正在使用该异步实例,它就不会准备好,您将遇到该问题。 对我来说,这是因为我使用了

locator.registerLazySingletonAsync<SharedPrefsService>(
      () async => SharedPrefsService.getInstance());
  
locator.registerLazySingleton<AuthLocal>(() => AuthLocalImpl());

我的 authlocal 类通过 di 使用sharedprefService 实例,这是错误的!

我的最终代码解决了我的问题是

 locator.registerSingletonAsync<SharedPrefsService>(
      () async => SharedPrefsService.getInstance());

  locator.registerLazySingleton(() => AppRouter());
© www.soinside.com 2019 - 2024. All rights reserved.