1. 程式人生 > >“一盤沙拉”帶你入門Dagger2(三)之@Qualifier

“一盤沙拉”帶你入門Dagger2(三)之@Qualifier

系列文章

當一個類有兩個建構函式時,使用Dagger2時,如何獲取指定建構函式new出來的物件

或者說雖然這有一個建構函式,但是這個建構函式new出了兩個具有不同屬性的物件,我們如何獲取到他們,比如Person類,他有一個屬性Sex,new了第一個Person,設定sex=“male”,new了第二個Person,設定sex=“female”,我們如何在注入依賴時候,準確注入一個男人或者女人呢

下面還是以兩個建構函式的問題為例說明問題,這個說明了,自然解釋了男人女人的問題

我們Salad裡要新增一種新水果—Apple,他有兩個建構函式,我們要在Salad類裡面,分別得到這兩個不同的建構函式new出的Apple物件,

使用@Qualifier限定符來解決這個問題

@Named(“String”)也能解決這個問題,只不過,傳遞的值只能是字串,用@Qualifier更靈活一點

  1. 新建Apple類

    public class Apple {
        String color;
    
        public Apple() {
            Log.e("TAG", "我是一個普通的蘋果");
    
        }
    
        public Apple(String color) {
            this.color = color;
            Log.e("TAG", "我是一個有顏色的蘋果");
    
        }
    
    }
  2. 自定義一個限定符,用來區分是哪個建構函式new出的物件

    /**
     * 自定義一個限定符
     */
    @Qualifier//限定符
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Type {
        String value() default "";//預設值為""
    }
  3. 修改 SaladModule,使用限定符@Type來區分不同的建構函式new出來的物件

    @Module
    public class SaladModule {
    
       .........
    
        @Type("normal")//使用限定符來區別使用哪個建構函式返回物件
    @Provides public Apple provideNormalApple() { return new Apple(); } @Type("color")//使用限定符來區別使用哪個建構函式返回物件 @Provides public Apple provideColorApple(String color) { return new Apple(color); } // 由於我們的Apple建構函式裡使用了String,所以這裡要管理這個String(★否則報錯) // int等基本資料型別是不需要這樣做的 @Provides public String provideString(){ return new String(); } }
  4. 修改SaladComponent

    @Component(modules = {SaladModule.class})//指明要在那些Module裡尋找依賴
    public interface SaladComponent {
    
        .........
    
        @Type("normal")//關鍵靠這個限定符來區分呼叫哪個建構函式
        Apple provideNormalApple();//這個方法名並不重要,只要是provide開頭就行,但是建議和module裡一致
    
        @Type("color")
        Apple provideColorApple();
    
    
        String provideString();
        //注意:下面的這個方法,表示要將以上的三個依賴注入到某個類中
        //這裡我們把上面的三個依賴注入到Salad中
        //因為我們要做沙拉
        void inject(Salad salad);
    
    }
  5. 在目標類Salad裡注入Apple依賴,我們要分別注入兩個建構函式new出的物件

    public class Salad {
    
      .........
    
        @Inject
        @Type("normal")
        Apple normalApple;
    
        @Inject
        @Type("color")
        Apple colorApple;
    
        public Salad() {
            // DaggerSaladComponent編譯時才會產生這個類,
            // 所以編譯前這裡報錯不要著急(或者現在你先build一下)
            SaladComponent saladComponent = DaggerSaladComponent.create();
            saladComponent.inject(this);//將saladComponent所連線的SaladModule中管理的依賴注入本類中
            makeSalad(pear, banana, saladSauce);
        }
    
        private void makeSalad(Pear pear, Banana banana, SaladSauce saladSauce) {
            Log.e("TAG", "我在攪拌製作水果沙拉");
        }
    }
  6. 測試

    09-01 14:57:14.559 31918-31918/com.demo.dagger2demo2 E/TAG: 我是一個梨
    09-01 14:57:14.560 31918-31918/com.demo.dagger2demo2 E/TAG: 我是一個香蕉
    09-01 14:57:14.560 31918-31918/com.demo.dagger2demo2 E/TAG: 我是沙拉醬
    09-01 14:57:14.561 31918-31918/com.demo.dagger2demo2 E/TAG: 我是一個小刀
    09-01 14:57:14.562 31918-31918/com.demo.dagger2demo2 E/TAG: 我可以切水果
    09-01 14:57:14.562 31918-31918/com.demo.dagger2demo2 E/TAG: 我是一個桔子
    09-01 14:57:14.562 31918-31918/com.demo.dagger2demo2 E/TAG: 我是一個小刀
    09-01 14:57:14.563 31918-31918/com.demo.dagger2demo2 E/TAG: 我是一個普通的蘋果
    09-01 14:57:14.563 31918-31918/com.demo.dagger2demo2 E/TAG: 我是一個有顏色的蘋果
    09-01 14:57:14.563 31918-31918/com.demo.dagger2demo2 E/TAG: 我在攪拌製作水果沙拉