如何结合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.
相关产品推荐
相关产品推荐

