creo que la propuesta de NamshubWriter no es muy guicy. Creo que en Guice, un constructor debería hacer exactamente una cosa: asignar parámetros a los campos. Si hay algo más que deba hacer, póngalo en una fábrica o en un proveedor.
En este caso, querremos un proveedor para A. El proveedor podría llamar directamente a la nueva B(), pero luego directamente uniríamos A a B, que es lo que intentamos evitar en primer lugar. Así que indirectamente, la creación de B sobre una fábrica, que Guice puede proporcionarnos a través de assistedInject. Este código se ejecuta y compila bien, y completamente desacopla A y B.
En un escenario realista, que había necesidad de ocultar detrás de A y B interfaces para tomar ventaja de la separación.
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.
Usted puede simplemente añadir @Inject al constructor de A. Estoy adivinando su clase real es algo más complicado. ¿B es una interfaz? ¿Necesita ser inyectado con algo además de A? Por cierto, dejar que el campo "este" escape al constructor es generalmente una mala idea. – NamshubWriter
No, B no es una interfaz sino una clase. Por supuesto, las dependencias de círculo no son buenas y puedo refactorizar estas dos clases, pero lo que realmente necesito es comprender la viabilidad de Guice. –