系列文章
“一盘沙拉”带你入门Dagger2(一)之HelloWorld
“一盘沙拉”带你入门Dagger2(三)之@Qualifier
“一盘沙拉”带你入门Dagger2(四)之 @Singleton
当一个类有两个构造函数时,使用Dagger2时,如何获取指定构造函数new出来的对象
或者说虽然这有一个构造函数,但是这个构造函数new出了两个具有不同属性的对象,我们如何获取到他们,比如Person类,他有一个属性Sex,new了第一个Person,设置sex=“male”,new了第二个Person,设置sex=“female”,我们如何在注入依赖时候,准确注入一个男人或者女人呢
下面还是以两个构造函数的问题为例说明问题,这个说明了,自然解释了男人女人的问题
我们Salad里要添加一种新水果—Apple,他有两个构造函数,我们要在Salad类里面,分别得到这两个不同的构造函数new出的Apple对象,
使用@Qualifier限定符来解决这个问题
@Named(“String”)也能解决这个问题,只不过,传递的值只能是字符串,用@Qualifier更灵活一点
新建Apple类
public class Apple { String color; public Apple() { Log.e("TAG", "我是一个普通的苹果"); } public Apple(String color) { this.color = color; Log.e("TAG", "我是一个有颜色的苹果"); } }
自定义一个限定符,用来区分是哪个构造函数new出的对象
/** * 自定义一个限定符 */ @Qualifier//限定符 @Documented @Retention(RetentionPolicy.RUNTIME) public @interface Type { String value() default "";//默认值为"" }
修改 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(); } }
修改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); }
在目标类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", "我在搅拌制作水果沙拉"); } }
测试
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: 我在搅拌制作水果沙拉