我试图理解Dagger 2中的组件.这是一个例子:
@Component(modules = { MyModule.class }) public interface MyComponent { void inject(InjectionSite injectionSite); Foo foo(); Bar bar(); }
我理解void inject()方法的作用.但我不明白其他Foo foo()getter方法的作用.这些其他方法的目的是什么?
Dagger是一种连接对象及其依赖关系图的方法.作为直接调用构造函数的替代方法,您可以通过从Dagger请求实例来获取实例,或者通过提供您希望使用Dagger创建的实例注入的对象来获取实例.
让我们做一个咖啡店,这取决于提供商< 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或服务用例的顶级和成员注入的工厂方法,或者任何其他类型的混合和匹配.
(注意:除了将它们用作对象图的入口点之外,no-arg getters称为提供方法对于公开组件依赖关系的绑定也很有用,正如David Rawson在other answer中所描述的那样.)