Trong câu hỏi này, tôi nói về Dagger2. Dagger2 bao gồm cơ bản về Components và Modules. Dưới đây là một ví dụ:Chậm ràng buộc đối với biểu đồ Dagger2 bằng cách sử dụng Chú giải xử lý
Giả sử tôi có một giao diện:
public interface MyCoolService {
void run();
}
và thực hiện tốt:
public class MyCoolServiceImpl {
@Override
void run() {}
}
tôi có thể liên kết thực hiện với giao diện sử dụng Dagger2 tạo:
@Component(modules = {MyModule.class})
@Singleton
public interface Component {
MyCoolService getMyCoolService();
}
và
@Module
public class MyModule {
@Provides @Singleton
MyCoolService provideMyCoolService() {
return new MyCoolServiceImpl();
}
}
Đây là phần giới thiệu ngắn gọn về Dagger2. Bây giờ giả sử tôi có giao diện sau:
public interface MySecondCoolService {
void doCoolStuff();
}
Không có thực hiện MySecondCoolServiceImpl
của MySecondCoolService
trong mã. Thay vào đó, tôi có một chú thích @JustForCoolStuff
để đánh dấu các trường và phương thức. Tôi đã tạo một bộ xử lý chú thích thu thập tất cả các chú thích này và tạo ra MySecondCoolServiceImpl
thực hiện MySecondCoolService
.
Tôi trình biên dịch biết giao diện mới MySecondCoolService
trước khi bộ xử lý chú thích đang chạy. Vì vậy, tôi có thể thay đổi thành phần của tôi là:
@Component(modules = {MyModule.class})
@Singleton
public interface Component {
MyCoolService getMyCoolService();
MySecondCoolService getMySecondCoolService();
}
Các vấn đề là tôi không có thực hiện được nêu ra trong mã và tôi không biết tên của việc thực hiện MySecondCoolService
sẽ được tạo ra bởi một bộ xử lý chú thích . Do đó, tôi không thể kết nối giao diện với việc thực hiện chính xác trong MyModule
. Những gì tôi có thể làm là thay đổi bộ xử lý chú thích của tôi sao cho nó tạo ra một mô-đun mới cho tôi. xử lý chú thích của tôi có thể tạo ra một mô-đun (MyGeneratedModule
) như thế này:
@Module
public class MyGeneratedModule {
@Provides @Singleton
MySecondCoolService provide MySecondCoolService() {
return new MySecondCoolServiceImpl();
}
}
Again MyGeneratedModule
được tạo ra bởi một bộ xử lý chú thích. Tôi không có quyền truy cập vào nó trước khi chạy bộ xử lý chú thích cũng tôi không biết tên.
Đây là vấn đề: Bộ xử lý chú thích bằng cách nào đó phải nói với Dagger2 rằng có một mô-đun mới mà Dagger2 cần tính đến. Kể từ khi bộ xử lý chú thích không thể thay đổi các file nó không thể kéo dài tuổi @Component(modules = {MyModule.class})
chú thích và thay đổi nó thành một cái gì đó như thế này: @Component(modules = {MyModule.class, MyGeneratedModule.class})
Có cách nào để thêm MyGeneratedModule
lập trình để đồ thị phụ thuộc dagger2? Bộ xử lý chú thích của tôi có thể nói với Dagger2 rằng cần có một hệ thống nối dây mới giữa giao diện và triển khai như tôi đã mô tả ở trên?
Foray: Tôi biết rằng một cái gì đó như thế có thể được thực hiện trong Google Guice và Google Gin. Một dự án thực hiện điều đó là GWTP.Ở đó bạn có Người trình bày:
public class StartPagePresenter extends ... {
@NameToken("start")
public interface MyProxy extends ProxyPlace<StartPagePresenter> {
}
...
}
có chú thích @NameToken
với giao diện ProxyPlace
. Trong bạn AbstractPresenterModule
bạn dây quan điểm với người dẫn chương trình và proxy:
public class ApplicationModule extends AbstractPresenterModule {
bindPresenter(StartPagePresenter.class,
StartPagePresenter.MyView.class, StartPageView.class,
StartPagePresenter.MyProxy.class);
...
}
Như vậy có thể thấy không thực hiện giao diện MyProxy
được đưa ra. Việc thực hiện được tạo ra bởi một máy phát điện (tương tự như bộ xử lý chú thích nhưng đối với GWT). Có Generator tạo ra việc thực hiện StartPagePresenter.MyProxy
và thêm nó vào hệ thống hướng dẫn/gin:
public class StartPagePresenterMyProxyImpl extends com.gwtplatform.mvp.client.proxy.ProxyPlaceImpl<StartPagePresenter> implements buddyis.mobile.client.app.start.StartPagePresenter.MyProxy, com.gwtplatform.mvp.client.DelayedBind {
private com.gwtplatform.mvp.client.ClientGinjector ginjector;
@Override
public void delayedBind(Ginjector baseGinjector) {
ginjector = (com.gwtplatform.mvp.client.ClientGinjector)baseGinjector;
bind(ginjector.getPlaceManager(),
ginjector.getEventBus());
presenter = new CodeSplitProvider<StartPagePresenter>(ginjector.getbuddyismobileclientappstartStartPagePresenter());
...
}
}
Tại sao không thể bạn chỉ cần viết '@Component (modules = {MyModule.class, MyGeneratedModule.class}) 'tại của bạn mã? –
@TavianBarnes Như tôi đã mô tả trong văn bản, tôi không biết tên 'MyGeneratedModule'' sẽ được tạo. –
Nếu bạn có một bộ xử lý chú thích tạo ra một lớp có tên bạn không biết trước, và không có cách nào khác để khởi tạo nó, thì bạn có một vấn đề. Sửa lỗi đầu tiên, phần còn lại sẽ theo sau. Cho dù bạn sử dụng Dagger hay không thực sự là không liên quan. –