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

如何结合get_it与injectable正确实现可销毁仓库的清理?

Flutter中用GetIt+Injectable实现登出时销毁依赖的正确方式

你遇到的核心问题是:getIt.getAll<Disposable>()拿不到实例,因为Injectable默认只注册具体类的类型,没有把RepoA、RepoB和抽象类Disposable关联起来。

下面是两种可行的解决思路:

思路1:让Injectable同时注册抽象类与具体类

修改仓库类的注解,用as参数指定抽象类类型,这样GetIt会同时把实例注册为具体类和Disposable类型:

abstract class Disposable {
  void dispose();
}

// 添加as: Disposable,同时注册为RepoA和Disposable类型
@lazySingleton(as: Disposable)
class RepoA extends Disposable {
  void printHello() {
    print('hello');
  }

  @override
  void dispose() {
    print('RepoA dispose');
    // 这里可以清理资源,比如取消订阅、关闭数据库连接等
  }
}

@lazySingleton(as: Disposable)
class RepoB extends Disposable {
  void printHelloFromRepoB() {
    print('hello from RepoB');
  }

  @override
  void dispose() {
    print('RepoB dispose');
  }
}

@injectable
class UseCase {
  UseCase(
    this.repoB,
    this.repoA,
  );

  final RepoB repoB;
  final RepoA repoA;
}

void disposeAllDisposables() {
  final disposables = getIt.getAll<Disposable>();
  for (var disposable in disposables) {
    disposable.dispose();
    // 销毁后从GetIt中移除实例,避免下次获取到已销毁的对象
    getIt.unregister<Disposable>(instance: disposable);
  }
}

这样调用disposeAllDisposables()就能正确获取所有实现了Disposable的实例并执行销毁逻辑。

思路2:遍历GetIt所有注册实例,筛选Disposable类型

如果不想修改原有注解,可以遍历GetIt的所有注册类型,检查实例是否是Disposable的子类:

void disposeAllDisposables() {
  // 遍历所有注册的类型
  for (var entry in getIt.registrations.entries) {
    final instance = entry.value.instance;
    if (instance is Disposable) {
      instance.dispose();
      getIt.unregister(entry.key);
    }
  }
}

这种方式不需要修改仓库类的注解,但需要注意:如果有同一个类型注册了多个实例,需要额外处理。

注意事项

  • 销毁实例后记得调用getIt.unregister()移除注册,否则下次获取时会返回已销毁的对象,导致异常。
  • 如果这些仓库是lazySingleton,登出后再次使用时需要重新初始化,或者改为factory类型(但factory每次都会创建新实例,根据业务需求选择)。

内容的提问来源于stack exchange,提问作者Yohan D. Angulo U.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:22:35