在我正在处理的一个项目中,我有 2 个高度相互依赖的类:
@Singleton
class WorkExecutor {
@Inject Provider<ExecutionServices> services;
...
public void execute(Work w){
w.execute(services.get());
...
}
...
}
class ExecutionServicesImpl implements ExecutionServices {
@Inject WorkExecutor executor;
...
}
这个想法是,当执行一项工作时,该工作可以访问多个服务 - 其中一个是执行者本身,因此一个工作将能够执行子工作。
可以看出,这里有一个循环依赖,但我发现它很难打破。
主要问题是 WorkExecutor 在构建图时实际上不需要 ExecutionServices 对象的实例,而只需要稍后使用的提供程序。遗憾的是,Dagger 不知道 WorkExecutor 不会从类的构造函数中调用 ExecutionServices 提供程序,因此它猜测 ExecutionServices 依赖于 WorkExecutor,反之亦然。
我发现的一种可能的解决方案是通过以下方式定义模块和组件:
interface DelayedProvider<T> extends Provider<T>{}
@Module
class AppModule {
Provider<ExecutionServices> delayedProvider = null;
@Provides DelayedProvider<ExecutionServices> provideDelayed() {
return () -> delayedProvider.get();
}
@Provides @Named("late-binding-conf") Void latebindingConf(Provider<ExecutionServices> eager){
this.delayedProvider = eager;
return null; //notice we returning Void and not void
}
}
@Component(modules=AppModule.class)
interface AppComponent {
App app();
@Named("late-binding-conf") Void configureLateBinding();
}
然后我将原始类修改为:
@Singleton
class WorkExecutor {
@Inject DelayedProvider<ExecutionServices> services;
...
public void execute(Work w){
w.execute(services.get());
...
}
...
}
class ExecutionServicesImpl implements ExecutionServices {
@Inject WorkExecutor executor;
...
}
然后为了创建我的应用程序,我必须这样做:
AppComponent acomp = DaggerAppComponent.create();
App = acomp.app();
acomp.configureLateBinding();
但我不确定这是正确的做法 - 有没有更好的方法?