В проекте я работаю у меня есть 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 фактически не нужен экземпляр объекта ExecutionServices во время построения графика, а только поставщик, который будет использоваться позже. К сожалению, Кинжал не знает, что 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();
Но я не уверен, что это правильно курс действий - есть ли лучший способ?
У меня такая же проблема. Вы когда-нибудь находили лучшее решение? – KennethJ
@ KennethJ, к сожалению нет .. – bennyl
Зачем «ExecutionServicesImpl» нужен «WorkExecutor»? Вы говорите, что это так, что работа может выполнять суб-объекты. Не могли бы вы просто передать 'WorkExecutor' самому методу' execute' 'Work' вместо того, чтобы быть членом' ExecutionServicesImpl'? – Frans