Trong một dự án tôi đang làm việc trên tôi có 2 lớp học mà phụ thuộc rất nhiều vào nhau:dao găm 2 tròn dependancy
@Singleton
class WorkExecutor {
@Inject Provider<ExecutionServices> services;
...
public void execute(Work w){
w.execute(services.get());
...
}
...
}
class ExecutionServicesImpl implements ExecutionServices {
@Inject WorkExecutor executor;
...
}
Ý tưởng là khi thực hiện một tác phẩm, tác phẩm có quyền truy cập vào một số dịch vụ - một trong số đó là bản thân người thực thi để một tác phẩm có thể thực thi các tác phẩm phụ.
Như người ta có thể thấy, có một phụ thuộc vòng tròn ở đây, nhưng tôi thấy rất khó để phá vỡ nó.
Vấn đề chính là WorkExecutor không thực sự cần một thể hiện của đối tượng ExecutionServices tại thời gian xây dựng đồ thị nhưng chỉ có một nhà cung cấp được sử dụng sau này. Thật đáng buồn, Dagger không biết rằng WorkExecutor sẽ không gọi nhà cung cấp ExecutionServices từ constructor của lớp để nó đoán rằng ExecutionServices phụ thuộc vào WorkExecutor và ngược lại.
Một giải pháp khả thi mà tôi tìm thấy là để xác định một mô-đun và thành phần theo cách sau:
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();
}
và sau đó tôi sẽ thay đổi các lớp học ban đầu là:
@Singleton
class WorkExecutor {
@Inject DelayedProvider<ExecutionServices> services;
...
public void execute(Work w){
w.execute(services.get());
...
}
...
}
class ExecutionServicesImpl implements ExecutionServices {
@Inject WorkExecutor executor;
...
}
Và sau đó theo thứ tự để tạo ứng dụng của tôi, tôi phải làm:
AppComponent acomp = DaggerAppComponent.create();
App = acomp.app();
acomp.configureLateBinding();
Nhưng tôi không chắc đây là hành động - Có cách nào tốt hơn không?
Tôi gặp sự cố tương tự. Bạn đã bao giờ tìm thấy một giải pháp tốt hơn? – KennethJ
@KennethJ, thật đáng buồn là không .. – bennyl
Tại sao 'ExecutionServicesImpl' lại cần' WorkExecutor'? Bạn nói điều này là để một công việc có thể thực hiện các subworks. Bạn không thể chỉ có 'WorkExecutor' tự chuyển sang phương thức' execute' 'execute' thay vì nó là thành viên của' ExecutionServicesImpl'? – Frans