文章目录
前面介绍了,使用Inject注解构造方法,实现注入。除此之外,Dagger还提供了另外两种方式注入。
Provides
对于第三方提供的类,我们无法在构造方法上添加Inject注解。
一个汽车生产商,使用其他公司提供的发动机Engine组装汽车Car。
我使用了Inject注解Car的构造方法。
public class Car {
private Engine engine;
@Inject
public Car(Engine engine) {
this.engine = engine;
}
}
由于Engine有三方提供,Engine是无法被Inject注解的。
public class Engine {
public Engine() {
}
}
针对这种情况,Dagger提供了Provider注解。
首先新增一个EngineMoudle类,使用Moudle注解,然后添加getEngine方法,返回一个Engine对象,使用Provides注解这个方法:
@Module
public class EngineMoudle {
@Provides
public Engine getEngine(){
return new Engine();
}
}
在CarComponent中,把EngineMoudle类作为参数赋给Component注解:
@Component(modules = EngineMoudle.class)
public interface CarComponent {
Car car();
}
build一下,进行测试:
@Test
public void testProvides(){
CarComponent carComponent = DaggerCarComponent.create();
Car car1 = carComponent.car();
System.out.println(car1);
}
输出:
Car@18bf3d14
Binds
发动机Engine不止一个品牌,有大众的,有福特的。作为汽车生产商,并不关心发动机的品牌。换句话说,发动机Engine在Car那里只是一个接口,Engine如何实现,Car并不关心。
现在有了Engine:
public class Engine {
public Engine() {
}
}
有两个发动机提供商,大众和福特:
public class AutoEngine extends Engine{
}
public class FocusEngine extends Engine{
}
我们依然需要EngineMoudle,但是EngineMoudle的任务不再自己提供Engine:
@Module
public class EngineMoudle {
}
EngineMoudle觉得,既然Engine都有各自的品牌商了,自己只要做个中介,把品牌商的Engine提供给Car就行了。这合理吗?这很合理。
于是品牌商纷纷建立了自己的Moudle,并在Moudle中提供自己的Engine:
@Module
public interface AutoEngineMoudle {
@Binds Engine bindEngine(AutoEngine autoEngine);
}
public class AutoEngine extends Engine{
//为构造方法添加注解,支持注入
@Inject
public AutoEngine() {
}
}
@Module
public interface FocusEngineMoudle {
@Binds Engine bindEngine(FocusEngine focusEngine);
}
public class FocusEngine extends Engine{
//为构造方法添加注解,支持注入
@Inject
public FocusEngine() {
}
}
经过竞标,EngineMoudle决定使用大众的发动机:
@Module(includes = AutoEngineMoudle.class)
public class EngineMoudle {
}
build一下,测试:
@Test
public void testBinds(){
CarComponent carComponent = DaggerCarComponent.create();
Car car1 = carComponent.car();
System.out.println(car1.getEngine());
}
输出:
AutoEngine@28ac3dc3
Dagger使用Binder注解,绑定接口和具体的实现。
使用Binder需要注意:
- 只能注解抽象方法
- 方法的参数只能有一个
- 参数必须是返回类型的子类