flutter - 在颤振上使用 get_it 对抗循环依赖?
问题描述
GetIt 是Dart 和 Flutter 项目的服务定位器( https://github.com/fluttercommunity/get_it )
我认为 GetIt 应该给我们一些关于循环依赖的细节。
例如,当我运行我的测试时,会有一个无限循环,它们永远不会结束。
解决方案
get_it 用于定义全局对象和服务,并提供用于访问它们的定位器功能。如果您的全局服务之间存在循环依赖关系,那么您很有可能将这些服务设计为彼此紧密耦合。例如:
class ServiceA {
final ServiceB b;
ServiceA(this.b);
void foo() {
b.bar();
}
void bar() { ... }
}
class ServiceB {
final ServiceA a;
ServiceB(this.a);
void foo() {
a.bar();
}
void bar() { ... }
}
// GetIt Initialization
GetIt g = GetIt.instance;
g.registerLazySingleton<ServiceA>(() => ServiceA(g.get<ServiceB>()));
g.registerLazySingleton<ServiceB>(() => ServiceB(g.get<ServiceA>()));
在此之后,调用GetIt.I.get
目标ServiceA
或者ServiceB
可能会创建由循环依赖引起的无限循环。有了这个实现,没有真正的方法可以防止循环,而不会进入检查和延迟执行的兔子洞。
循环依赖的真正解决方案通常很简单:将您的应用设计为一开始就没有它。例如,在上面的例子中,在构造函数中ServiceA
具有刚性依赖,ServiceB
反之亦然。相反,服务可以使用服务定位器在执行需要它的方法期间获取对必要服务的引用。换句话说,我们已经在使用 get_it,为什么不在这里使用呢?
class ServiceA {
ServiceA();
void foo() {
final b = GetIt.I.get<ServiceB>();
b.bar();
}
void bar() { ... }
}
class ServiceB {
ServiceB();
void foo() {
final a = GetIt.I.get<ServiceA>();
a.bar();
}
}
// GetIt Initialization
GetIt g = GetIt.instance;
g.registerLazySingleton<ServiceA>(() => ServiceA());
g.registerLazySingleton<ServiceA>(() => ServiceB());
现在,彼此之间的依赖关系更加动态,并且不依赖于它们各自的构造函数ServiceA
。ServiceB
不再存在循环依赖问题,并且 get_it 初始化器在访问单例时将没有问题。
推荐阅读
- reactjs - Materialize class="validate" 属性不是 React 中的验证字段
- web-scraping - Scrapy 类中多个解析定义的正确输出
- linux-kernel - 我可以使用内核模块模拟具有硬件地址的硬件设备吗?(编辑:将路由到我的模块的虚拟地址)
- python - 是否在列表文字中立即创建了一个类的实例?
- r - 使用 rvest 在一个页面中提取多个表
- php - 意外的状态行:在 HttpURLConnection 上使用 getInputStream() 时出现 Y������
- python - 相同 Keras CNN 的不同预测
- java - 这里的注释是什么意思?
- git - 如何将分支内容移动到另一个存储库以保留历史记录并避免复制原始存储库的完整历史记录?
- docker - 容器之间的连接被拒绝