匕首 2 圆形依赖性
在我正在处理的项目中,我有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 实际上不需要在图构造时执行服务对象的实例,而只需要一个稍后使用的提供程序。可悲的是,Dagger不知道WorkExecutor不会从类的构造函数调用执行服务提供程序,因此它猜测执行服务依赖于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();
但我不确定这是正确的行动方案 - 有没有更好的方法?