Dagger 是一种连接对象及其依赖关系图的方法。作为直接调用构造函数的替代方法,您可以通过从 Dagger 请求实例来获取实例,或者通过提供您希望注入 Dagger 创建的实例的对象来获取实例。
让我们创建一家咖啡店,这取决于 Provider<Coffee> 和 CashRegister。假设您已将它们连接到一个模块中(可能是 LightRoastCoffee 和 DefaultCashRegister 实现)。
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); // to be discussed below
}
当您调用 getCoffeeShop 时,Dagger 创建 Provider<Coffee> 以提供 LightRoastCoffee,创建 DefaultCashRegister,将它们提供给 Coffeeshop 构造函数,然后返回结果。恭喜,您自豪地拥有一家全连接的咖啡店。
现在,所有这些都是替代void 注入方法,它采用已创建的实例并注入其中:
public class CoffeeService extends SomeFrameworkService {
@Inject CoffeeShop coffeeShop;
@Override public void initialize() {
// Before injection, your coffeeShop field is null.
DaggerCoffeeShopComponent.create().inject(this);
// Dagger inspects CoffeeService at compile time, so at runtime it can reach
// in and set the fields.
}
@Override public void alternativeInitialize() {
// The above is equivalent to this, though:
coffeeShop = DaggerCoffeeShopComponent.create().getCoffeeShop();
}
}
所以,你有了它:两种不同的样式,这两种样式都可以让你访问完全注入的对象图,而无需列出或关心它们需要哪些依赖项。您可以选择其中一种,或者更喜欢顶级工厂方法和 Android 或服务用例的成员注入,或任何其他类型的混合搭配。
(注意: 除了用作对象图的入口点之外,称为 provision 方法 的无参数 getter 也可用于公开组件依赖项的绑定,因为David Rawson 在other answer 中描述。)