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

bas*_*kwo 1 java dependency-injection dagger-2

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

我曾经为此使用 Guice 来调用MembersInjector#injectMembersInjector#injectMembers。我怎么能在 Dagger 2 中有这样的东西?

Dav*_*son 7

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

假设您有一个包含要注入的字段的 CoffeeShop:

class CoffeeShop {

    @Inject CoffeeMaker coffeeMaker;

    CoffeeShop() { 
        //we're not using constructor injection here 
        //although we probably should be :/
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@Component(modules = { CoffeeModule.class })
interface CoffeeComponent {
    void inject(CoffeeShop coffeeShop);
}
Run Code Online (Sandbox Code Playgroud)

因此,在另一个类中,您可以执行以下操作:

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();
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以在 Dagger 2 组件中定义配置方法,这将允许您解析特定类的实例。

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

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

  void inject(CoffeeService serviceToInject); // to be discussed below
}
Run Code Online (Sandbox Code Playgroud)

假设你有一个 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();
    }
}
Run Code Online (Sandbox Code Playgroud)