2016-12-11 22 views
6

Để tìm hiểu Dagger 2 tôi quyết định viết lại ứng dụng của mình nhưng tôi bị kẹt với việc tìm ra giải pháp thích hợp cho vấn đề sau.Dagger 2: cách thay đổi các phụ thuộc được cung cấp trong thời gian chạy

Đối với mục đích của ví dụ này chúng ta hãy giả sử chúng ta có một giao diện được gọi Mode:

public interface Mode { 
    Object1 obj1(); 

    //some other methods providing objects for app 
} 

và hai triển khai: NormalModeDemoMode.

Chế độ được lưu trữ ở dạng đơn để có thể truy cập từ mọi nơi trong ứng dụng.

public enum ModeManager { 
    INSTANCE,; 

    private Mode mode; 

    public Mode mode() { 
    if (mode == null) 
     mode = new NormalMode(); 
    return mode; 
    } 

    public void mode(Mode mode) { //to switch modules at runtime 
    this.mode = mode; 
    } 
} 

Các NormalMode được chuyển sang DemoMode lúc runtime (giả sử, khi clickcs người dùng trên vài nền lần)

public void backgroundClicked5Times(){ 
    ModeManager.INSTANCE.mode(new DemoMode()); 
    //from now on every object that uses Mode will get Demo implementations, great! 
} 

Vì vậy, đầu tiên tôi đã thoát khỏi những singleton và xác định chế độ như Dagger 2 mô-đun:

@Module 
public class NormalModeModule { 
    @Provides 
    public Object1 provideObject1() { 
    return new NormalObject1(); 
    } 
} 

@Module 
public class DemoModeModule { 
    @Provides 
    public Object1 provideObject1() { 
    return new DemoObject1(); 
    } 
} 

Bây giờ trong phương pháp backgroundClicked5Times trong thay vì giao dịch với singleton tôi muốn thay thế NormalModeModule bằng DemoModeModule trong DAG để các lớp khác cần Object1 sẽ nhận được thực thi DemoObject1 kể từ bây giờ.

Tôi có thể làm điều đó như thế nào trong Dagger?

Xin cảm ơn trước.

+0

có thể trùng lặp của [mô-đun với Dagger thể thay thế nhanh 2] (https://stackoverflow.com/questions/35658488/swappable-modules-with-dagger-2) – tir38

Trả lời

1

Đã thử nghiệm với dao găm trong một thời gian tôi đưa ra giải pháp có vẻ hoạt động tốt trong trường hợp sử dụng của tôi.

  1. Xác định lớp đó sẽ tổ chức thông tin trạng thái về chế độ

    public class Conf { 
        public Mode mode; 
    
        public Conf(Mode mode) { 
        this.mode = mode; 
        } 
    
        public enum Mode { 
        NORMAL, DEMO 
        } 
    } 
    
  2. Cung cấp dụ singleton của Conf trong Module

    @Module 
    public class ConfModule { 
        @Provides 
        @Singleton 
        Conf provideConf() { 
        return new Conf(Conf.Mode.NORMAL); 
        } 
    } 
    
  3. Thêm module để AppComponent

    @Singleton 
    @Component(modules = {AppModule.class, ConfModule.class}) 
    public interface AppComponent { 
        //... 
    } 
    
  4. Xác định module cung cấp đối tượng khác nhau dựa trên chế độ

    @Module 
    public class Object1Module { 
    
        @Provides 
        Object1 provideObject1(Conf conf) { 
        if (conf.mode == Conf.Mode.NORMAL) 
         return new NormalObject1(); 
        else 
         return new DemoObject1(); 
        } 
    } 
    
  5. Để chuyển chế độ trong thời gian chạy chỉ đơn giản là tiêm Conf đối tượng và sửa đổi nó:

    public class MyActivity extends Activity { 
        @Inject Conf conf; 
    
        //... 
    
        public void backgroundClicked5Times(){ 
         conf.mode = Conf.Mode.DEMO; 
    
         //if you have dagger objects in this class that depend on Mode 
         //execute inject() once more to refresh them 
        } 
    } 
    
+0

Có vẻ như một cách tốt để làm điều này, nhưng điều này sẽ không hoạt động khi phụ thuộc được cung cấp (mà sẽ được thay thế d lúc chạy) là một singleton, phải không? –

+1

Có, nếu bạn chú thích 'offerObject1' với' @ Singleton', nó sẽ không hoạt động, nhưng mặt khác nó mâu thuẫn với ý tưởng trong trường hợp sử dụng này. Nếu bạn muốn thay thế các đối tượng trong thời gian chạy thì bạn không thể đánh dấu một phương thức như vậy với '@ Singleton'. Mặt khác, bạn có thể tạo các tệp đơn giản 'NormalObject1' và' DemoObject1' để phương thức cung cấp các phụ thuộc sẽ không tạo ra nhiều hơn 2 trường hợp. – Marcin

+0

Câu cuối cùng đó là thông tin tôi cần. Giải pháp tuyệt vời, thx :) –

Các vấn đề liên quan