Dagger multibinding java - 用于两个或多个实现

问题描述

我正在尝试用 Java 代码(不是 Android)为具有两个或多个实现的接口创建 Dagger。我能够使用 javax 库通过 CDI 成功地做到这一点,但这次我想根据我的项目需要使用 Dagger。我无法在编译期间调用正确的实现或事件来解决依赖关系。我收到多个绑定或缺少绑定的错误

我是 Dagger2 的新手,正在尝试解决这个问题。

所以我首先开始创建一个界面:

public interface Engine {
     public startEngine();
}

引擎有汽油和柴油两种实现

public class PetrolEngine implements Engine {

     @Inject
     public PetrolEngine(){}

     @Override
     public startEngine() {
       System.out.println("Petrol Engine Start");
     }
}
public class DieselEngine implements Engine {

     @Inject
     public DieselEngine(){}

     @Override
     public startEngine() {
       System.out.println("Diesel Engine Start");
     }
}

模块创建为

@Module
public class EngineModule {

     @Provides
     @IntoMap
     @StringKey("Petrol")
     public Engine providesEngine(PetrolEngine petrolEngine){
          return petrolEngine;
     }

     @Provides
     @IntoMap
     @StringKey("Diesel")
     public Engine providesEngine(DieselEngine dieselEngine){
          return dieselEngine;
     }
}

组件

@Component(module = EngineModule.class)
public interface EngineComponent {

    Engineservice providesEngineservice();
}

最后是调用汽油或柴油的服务

public call Engineservice {

  private Engine engine;

  @Inject
  public Engineservice(Engine engine) {
       this.engine = engine;
  }

  public void getEngineInstance() {
  //Some code to get the Petrol/Diesel Engine Instance
  }

}

解决方法

在 EngineService 中,您需要注入一个 Map<String,Engine> 或一个 Map<String,Provider<Engine>>,而不是注入 Engine。与 the docs 中一样,Map<String,Provider<Engine>> “当您不想实例化所有值时很有用,因为您将一次提取一个值,或者因为您想要获得一个每次查询地图时每个值的潜在新实例”。

public call EngineService {

  private final Map<String,Engine> engineMap;

  @Inject
  public EngineService(Map<String,Engine> engineMap) {
    this.engineMap = engineMap;
  }

  public void getEngineInstance() {
    engineMap.get("Petrol"); // to get a PetrolEngine
    engineMap.get("Diesel"); // to get a DieselEngine
  }
}

请注意,在实际示例中,如果 @StringKey("Petrol") Engine 的唯一实际绑定是 PetrolEngine,您不妨直接注入 PetrolEngine,其中 @StringKey("Motorcycle") Engine@StringKey("Lorry") Engine 可能会突出显示Dagger 更实用的那种配置。此外,像您这样简单的绑定也可以使用 @Binds annotation 来表达(尽管您现在的表达方式还可以)。