2015-04-23 23 views
10

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();  
} 

@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 GuiceGoogle 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()); 
    ... 
    } 
    } 

+0

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ã? –

+0

@TavianBarnes Như tôi đã mô tả trong văn bản, tôi không biết tên 'MyGeneratedModule'' sẽ được tạo. –

+3

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. –

Trả lời

0

Vâng, Có vẻ như bạn sẽ phải nghỉ mát để phản ánh cho một này ...

@Module 
public class MyGeneratedModule { 

    @Provides @Singleton 
    MySecondCoolService provide MySecondCoolService() { 
     try { 
      return (MySecondCoolService) Class.forName("package.MySecondCoolServiceImpl").newInstance(); 
     } catch (Exception ex) { ... } 
    } 
} 
1

Có cách nào để thêm MyGeneratedModule theo chương trình vào biểu đồ phụ thuộc dagger2 không?

Có. Sử dụng một đối số hàm tạo trong mô-đun của bạn.

@Module 
public class MyModule { 
    private final MyCoolService serviceImpl; 

    public MyModule(MyCoolService serviceImpl) { 
    this.serviceImpl = serviceImpl; 
    } 

    @Provides @Singleton 
    MyCoolService provideMyCoolService() { 
    return new MyCoolServiceImpl(); 
    } 
} 

Khởi tạo các serviceImpl được thực hiện khi bạn xây dựng đồ thị:

DaggerComponent.builder().myModule(new MyModule(serviceImpl)).build(); 
Các vấn đề liên quan