Dagger是一种将对象图和它们的依赖关系连接起来的方法。与直接调用构造函数的方式不同,您可以通过从Dagger请求实例或提供希望使用Dagger创建实例的对象来获取实例。
让我们假设您已经在一个模块中将咖啡店(可能是LightRoastCoffee和DefaultCashRegister的实现)所依赖的
Provider<Coffee>
和CashRegister连接好了。
public class CoffeeShop {
private final Provider<Coffee> coffeeProvider;
private final CashRegister register;
@Inject
public CoffeeShop(Provider<Coffee> coffeeProvider, CashRegister register) {
this.coffeeProvider = coffeeProvider;
this.register = register;
}
public void serve(Person person) {
cashRegister.takeMoneyFrom(person);
person.accept(coffeeProvider.get());
}
}
现在您需要获取该CoffeeShop的实例,但它只有一个包含其依赖项的两个参数构造函数。那么您该怎么做呢?简单:您告诉Dagger在生成的Component实例上提供一个工厂方法。
@Component(modules = {/* ... */})
public interface CoffeeShopComponent {
CoffeeShop getCoffeeShop();
void inject(CoffeeService serviceToInject);
}
当您调用
getCoffeeShop
时,Dagger会创建
Provider<Coffee>
以提供LightRoastCoffee,创建DefaultCashRegister并将它们提供给Coffeeshop构造函数,然后返回结果。恭喜,您现在拥有一个完全连接的咖啡店。
现在,所有这些都是
替代void
注入方法的,这些方法需要一个已经创建的实例并将其注入其中:
public class CoffeeService extends SomeFrameworkService {
@Inject CoffeeShop coffeeShop;
@Override public void initialize() {
DaggerCoffeeShopComponent.create().inject(this);
}
@Override public void alternativeInitialize() {
coffeeShop = DaggerCoffeeShopComponent.create().getCoffeeShop();
}
}
所以,你现在拥有两种不同的风格,它们都可以让你访问完全注入的对象图,而无需列出或关注它们需要哪些依赖项。你可以偏爱其中一种,或者喜欢顶层使用工厂方法和成员注入用于Android或服务用例,或者任何其他混合搭配方式。
(注意:除了作为进入对象图的入口之外,被称为“提供方法”的无参数getter还可用于公开组件依赖项的绑定,正如David Rawson在
其他答案中描述的那样。)