如何使用Dagger 2在运行时注入字段?

时间:2017-05-13 22:54:12

标签: java dependency-injection dagger-2

我需要按需注入其中一个类的实例的字段,即在运行时,因为我在运行时实例化它们。

我过去常常使用Guice来调用MembersInjector#injectMembersInjector#injectMembers。我怎么能在Dagger 2中有这样的东西?

2 个答案:

答案 0 :(得分:2)

Dagger 2 Components是Guice Injectors的对应物,因此在Dagger 2中执行此操作的方法是指定要在运行时作为注入站点注入其字段并从组件请求注入的对象。

让我们假设您有一个咖啡店,其中包含您要注入的字段:

class CoffeeShop {

    @Inject CoffeeMaker coffeeMaker;

    CoffeeShop() { 
        //we're not using constructor injection here 
        //although we probably should be :/
    }
}

您可以将CoffeeShop指定为组件内的注入站点,并从中请求注入:

@Component(modules = { CoffeeModule.class })
interface CoffeeComponent {
    void inject(CoffeeShop coffeeShop);
}

所以在另一个课程中你可以这样做:

private CoffeeComponent coffeeComponent;

void initComponent() {
    coffeeComponent = DaggerCoffeeComponent
                         .builder()
                         .coffeeModule(new CoffeeModule())
                         .build();
}

void makeCoffee() {  
    CoffeeShop coffeeShop = new CoffeeShop();
    coffeeComponent.inject(coffeeShop); //inject members of coffeeShop
    coffeeShop.makeCoffee();
}

或者,您可以在Dagger 2组件中定义provision methods,这将允许您解决特定类的实例。

如果您查看链接问题中的Jeff Bowman's示例,您会看到有这样的组件:

@Component(modules = {/* ... */})
public interface CoffeeShopComponent {
  CoffeeShop getCoffeeShop();

  void inject(CoffeeService serviceToInject); // to be discussed below
}

然后说你有一个CoffeeService。您现在可以调用getCoffeeShop()来获取CoffeeShop的任意实例:

class CoffeeService extends SomeFrameworkService {

    private CoffeeComponent coffeeComponent;

    void initComponent() {
        coffeeComponent = DaggerCoffeeComponent
                              .builder()
                              .coffeeModule(new CoffeeModule());
                              .build();
    }

    public CoffeeShop createCoffeeShop() {
        return coffeeComponent.getCoffeeShop(); //equivalent to Injector.getInstance();
    }
}

答案 1 :(得分:1)

在发布此问题时,我不知道Dagger2在@BindsInstance@Subcomponent.Factory中支持@Component.Factory,但到目前为止,在运行时注入实例的最佳方法是似乎正在使用这些。

在Dagger2教程中,有一个示例(https://dagger.dev/tutorial/10-deposit-after-login)用于创建接收实例的子组件。