【Android】Dagger:使用Provides和Binds注入

文章目录


前面介绍了,使用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需要注意:

  • 只能注解抽象方法
  • 方法的参数只能有一个
  • 参数必须是返回类型的子类
上一篇:Chapter 2- 微服务解决方案之 Spring Cloud


下一篇:「洛谷1600」「NOIP2016提高组」天天爱跑步【树上差分】