In einem Projekt arbeite ich an I 2 Klassen haben, die aufeinander stark abhängig sind:Dolch 2 Kreis dependancy
@Singleton
class WorkExecutor {
@Inject Provider<ExecutionServices> services;
...
public void execute(Work w){
w.execute(services.get());
...
}
...
}
class ExecutionServicesImpl implements ExecutionServices {
@Inject WorkExecutor executor;
...
}
Die Idee ist, dass, wenn eine Arbeit ausführt, die Arbeit Zugriff auf mehrere Dienste hat - Einer von ihnen ist der Executor selbst, so dass eine Arbeit Subarbeiten ausführen kann.
Wie man sehen kann, gibt es hier eine zirkuläre Abhängigkeit, die ich aber sehr schwer zu brechen fand.
Das Hauptproblem besteht darin, dass der WorkExecutor tatsächlich keine Instanz des ExecutionServices-Objekts zur Entwurfszeit des Diagramms benötigt, sondern nur einen Anbieter, der später verwendet werden kann. Leider weiß Dagger nicht, dass der WorkExecutor den ExecutionServices-Provider nicht vom Konstruktor der Klasse aufruft, so dass er davon ausgeht, dass ExecutionServices von WorkExecutor und umgekehrt abhängt.
Eine mögliche Lösung, die ich gefunden ist ein Modul und Komponente in der folgenden Art und Weise zu definieren:
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();
}
und modifiziert dann ich die ursprünglichen Klassen zu sein:
@Singleton
class WorkExecutor {
@Inject DelayedProvider<ExecutionServices> services;
...
public void execute(Work w){
w.execute(services.get());
...
}
...
}
class ExecutionServicesImpl implements ExecutionServices {
@Inject WorkExecutor executor;
...
}
Und dann, um meine App erstellen ich habe zu tun:
AppComponent acomp = DaggerAppComponent.create();
App = acomp.app();
acomp.configureLateBinding();
Aber ich bin nicht sicher, ob dies die richtige ist Vorgehensweise - Gibt es einen besseren Weg?
Ich habe ein ähnliches Problem. Haben Sie jemals eine bessere Lösung gefunden? – KennethJ
@KennethJ, leider nicht .. – bennyl
Warum benötigt 'ExecutionServicesImpl' einen' WorkExecutor'? Sie sagen, dies ist so, dass eine Arbeit Subworks ausführen kann. Könnte man nicht einfach den 'WorkExecutor' an die' execute' Methode von 'Work' übergeben, anstatt ein Mitglied von' ExecutionServicesImpl' zu sein? – Frans