问题描述
我正在尝试用 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 来表达(尽管您现在的表达方式还可以)。