Tôi nghĩ rằng đề xuất của NamshubWriter không phải là rất có ý nghĩa. Tôi nghĩ rằng trong Guice, một nhà xây dựng nên làm chính xác một điều: gán các tham số vào các trường. Nếu bạn cần làm gì khác, hãy đặt nó vào một nhà máy hoặc một nhà cung cấp.
Trong trường hợp này, chúng tôi sẽ muốn một nhà cung cấp cho A. Nhà cung cấp có thể gọi trực tiếp B mới(), nhưng sau đó chúng tôi trực tiếp ghép đôi A đến B, đó là những gì chúng tôi đã cố gắng tránh ngay từ đầu. Vì vậy, chúng tôi gián tiếp tạo ra B trên một nhà máy, mà guice có thể cung cấp cho chúng tôi thông qua assistedInject. Mã này chạy và biên dịch tốt và hoàn toàn tách A và B.
Trong trường hợp thực tế, bạn cần ẩn A và B phía sau giao diện để tận dụng lợi thế của việc tách.
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.
Bạn chỉ có thể thêm @Inject để các nhà xây dựng cho A. Tôi đoán lớp thực tế của bạn là chút phức tạp hơn. B là một giao diện? Liệu nó cần phải được tiêm với một cái gì đó bên cạnh A? BTW, cho phép trường "này" thoát khỏi hàm khởi tạo thường là một ý tưởng tồi. – NamshubWriter
Không, B không phải là giao diện mà là một lớp. Tất nhiên, sự phụ thuộc vòng tròn không tốt và tôi có thể cấu trúc lại hai lớp này, nhưng điều tôi thực sự cần là hiểu tính khả thi của Guice. –