Uważam, że propozycja NamshubWriter nie jest zbyt ostra. Myślę, że w Guice konstruktor powinien zrobić dokładnie jedną rzecz: przypisać parametry do pól. Jeśli jest coś jeszcze, co musisz zrobić, umieść w fabryce lub dostawcy.
W tym przypadku będziemy potrzebować operatora dla A. Dostawca może bezpośrednio wywołać nowe B(), ale wtedy będziemy bezpośrednio łączyć A do B, czego staraliśmy się uniknąć w pierwszej kolejności. Tak więc pośrednio tworzymy B w fabryce, która może nam zapewnić guess poprzez assistedInject. Ten kod działa i kompiluje się dobrze, a całkowicie oddziela A i B.
W realistycznym scenariuszu trzeba ukryć interfejsy A i B za sobą, aby skorzystać z separacji.
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.FactoryProvider;
public class Try {
public static void main(String[] args) {
System.out.println(
Guice.createInjector(new MyModule()).getInstance(A.class)
);
}
}
class MyModule extends AbstractModule {
public void configure() {
bind(A.class).toProvider(AProvider.class);
bind(IBFactory.class).toProvider(
FactoryProvider.newFactory(IBFactory.class, B.class));
}
}
class A {
B b;
public void setB(B b) {
this.b = b;
}
}
class B {
A a;
@Inject
B(@Assisted A a) {
this.a = a;
}
}
class AProvider implements Provider<A> {
private final IBFactory bFactory;
@Inject
AProvider(IBFactory bFactory) {
this.bFactory = bFactory;
}
public A get() {
A a = new A();
a.setB(bFactory.create(a));
return a;
}
}
interface IBFactory {
public B create(A a);
}
I made an extended version of the circular dependency injection in Guice where A and B are hidden behind interfaces.
można po prostu dodać @Inject do konstruktora A. Zgaduję aktualną klasę jest nieco bardziej skomplikowana. Czy B jest interfejsem? Czy trzeba wstrzykiwać coś poza A? Przyzwalanie, że "to" pole ucieka przed konstruktorem, to generalnie zły pomysł. – NamshubWriter
Nie, B nie jest interfejsem, ale klasą. Oczywiście, zależności między okręgami nie są dobre i mogę refaktoryzować te dwie klasy, ale to, czego naprawdę potrzebuję, to zrozumieć wykonalność Guice. –