Dagger2 在 class 注入时出错
Dagger2 Error at inject in a class who injects
我试图在我的 presenter
中 inject
一个 interactor
但是给了我一个错误,似乎我无法注入一个 class 谁注入另一个:
error: [Dagger/DuplicateBindings] com.example.calculadora.Data.Interactor.Operacion is bound multiple times:
@Provides com.example.calculadora.Data.Interactor.Operacion com.example.calculadora.Inject.InteractorModule.provideDiv()
@Provides com.example.calculadora.Data.Interactor.Operacion com.example.calculadora.Inject.InteractorModule.provideMult()
@Provides com.example.calculadora.Data.Interactor.Operacion com.example.calculadora.Inject.InteractorModule.provideResta()
@Provides com.example.calculadora.Data.Interactor.Operacion com.example.calculadora.Inject.InteractorModule.provideSuma()
com.example.calculadora.Data.Interactor.Operacion is injected at
com.example.calculadora.Domain.PresenterImpl.operacion
com.example.calculadora.Domain.PresenterImpl is injected at
com.example.calculadora.Inject.InteractorComponent.inject(com.example.calculadora.Domain.PresenterImpl)
这是我的 InteractorModule
,他为我提供了 4 个 classes,具体取决于我想使用的内容以及问题所在:
@Module
public class InteractorModule {
@Provides
public Operacion provideSuma() {
return new InteractorSuma();
}
@Provides
public Operacion provideResta() {
return new InteractorResta();
}
@Provides
public Operacion provideDiv() {
return new InteractorDivision();
}
@Provides
public Operacion provideMult() {
return new InteractorMultiplicacion();
}
}
我想在这里注入而不是初始化新项目:
@Override
public void setCalculo() {
Operacion operacion = null;
String[] operandos = vista.getOperandos();
Operando operando1 = new Operando(Integer.parseInt(operandos[0]));
Operando operando2 = new Operando(Integer.parseInt(operandos[1]));
switch (tipoOperacion) {
case SUMA:
operacion = new InteractorSuma(operando1, operando2);
break;
case RESTA:
operacion = new InteractorResta(operando1, operando2);
break;
case MULT:
operacion = new InteractorMultiplicacion(operando1, operando2);
break;
case DIV:
operacion = new InteractorDivision(operando1, operando2);
break;
}
operacion.calcular();
vista.mostrarResultado(String.valueOf(operacion.getResultado().getValor()));
}
Return 子实例 class,而不是父实例 class。
@Module
public class InteractorModule {
@Provides
public InteractorSuma provideSuma() {
return new InteractorSuma();
}
@Provides
public InteractorResta provideResta() {
return new InteractorResta();
}
@Provides
public InteractorDivision provideDiv() {
return new InteractorDivision();
}
@Provides
public InteractorMultiplicacion provideMult() {
return new InteractorMultiplicacion();
}
}
您应该将 one-other 与 @Named("someName")
注释分开,或者您可以按照@Derek 所说的进行操作。我的做法:
@Provides
@Named("someName1")
public Operacion provideSuma() {
return new InteractorSuma();
}
@Provides
@Named("someName2")
public Operacion provideResta() {
return new InteractorResta();
}
@Provides
@Named("someName3")
public Operacion provideDiv() {
return new InteractorDivision();
}
@Provides
@Named("someName4")
public Operacion provideMult() {
return new InteractorMultiplicacion();
}
不然dagger不知道哪一个到return哪里。
注入时也调用@Named
。
对于这种情况,Dagger2 Qualifiers
就是为这种情况而构建的。
1.- 创建您的预选赛:
@Qualifier
public @interface OperacionSuma {}
@Qualifier
public @interface OperacionResta {}
@Qualifier
public @interface OperacionDiv {}
@Qualifier
public @interface OperacionMult {}
2.- 在您的提供者方法中设置限定符:
@Module
public class InteractorModule {
@Provides
@OperacionSuma
public Operacion provideSuma() {
return new InteractorSuma();
}
@Provides
@OperacionResta
public Operacion provideResta() {
return new InteractorResta();
}
@Provides
@OperacionDiv
public Operacion provideDiv() {
return new InteractorDivision();
}
@Provides
@OperacionMult
public Operacion provideMult() {
return new InteractorMultiplicacion();
}
}
3.- 指定您想在演示者中注入哪种 "operation":
class Presenter {
@Inject
Presenter(@OperacionSuma Operacion operacion) { }
@Inject
Presenter(@OperacionResta Operacion operacion) { }
@Inject
Presenter(@OperacionDiv Operacion operacion) { }
@Inject
Presenter(@OperacionMult Operacion operacion) { }
}
由于 dagger 查找 return 类型,而不是为函数指定的名称,因此您应该注意它。但是,Dagger2 提供了解决此类问题的方法。使用@Named 注解。
Sometimes the type alone is insufficient to identify a dependency. For example, if you need a Refrofit instance with GsonConverterFactory and another one ScalarConverterFactory you will end up with 2 provide methods that have the same return type: Retrofit. In this case, you can use @Named annotation to differentiate two Retrofit instances
现在可以像下面这样使用了
来处理你的情况
@Module
public class InteractorModule {
@Provides
@Named("InteractorSuma")
public Operacion provideSuma() {
return new InteractorSuma();
}
@Provides
@Named("InteractorResta")
public Operacion provideResta() {
return new InteractorResta();
}
@Provides
@Named("InteractorDivision")
public Operacion provideDiv() {
return new InteractorDivision();
}
@Provides
@Named("InteractorMultiplicacion")
public Operacion provideMult() {
return new InteractorMultiplicacion();
}
}
Here is 如何使用 @Named
注释的完整示例
如果您还有问题,请告诉我
我试图在我的 presenter
中 inject
一个 interactor
但是给了我一个错误,似乎我无法注入一个 class 谁注入另一个:
error: [Dagger/DuplicateBindings] com.example.calculadora.Data.Interactor.Operacion is bound multiple times:
@Provides com.example.calculadora.Data.Interactor.Operacion com.example.calculadora.Inject.InteractorModule.provideDiv()
@Provides com.example.calculadora.Data.Interactor.Operacion com.example.calculadora.Inject.InteractorModule.provideMult()
@Provides com.example.calculadora.Data.Interactor.Operacion com.example.calculadora.Inject.InteractorModule.provideResta()
@Provides com.example.calculadora.Data.Interactor.Operacion com.example.calculadora.Inject.InteractorModule.provideSuma()
com.example.calculadora.Data.Interactor.Operacion is injected at
com.example.calculadora.Domain.PresenterImpl.operacion
com.example.calculadora.Domain.PresenterImpl is injected at
com.example.calculadora.Inject.InteractorComponent.inject(com.example.calculadora.Domain.PresenterImpl)
这是我的 InteractorModule
,他为我提供了 4 个 classes,具体取决于我想使用的内容以及问题所在:
@Module
public class InteractorModule {
@Provides
public Operacion provideSuma() {
return new InteractorSuma();
}
@Provides
public Operacion provideResta() {
return new InteractorResta();
}
@Provides
public Operacion provideDiv() {
return new InteractorDivision();
}
@Provides
public Operacion provideMult() {
return new InteractorMultiplicacion();
}
}
我想在这里注入而不是初始化新项目:
@Override
public void setCalculo() {
Operacion operacion = null;
String[] operandos = vista.getOperandos();
Operando operando1 = new Operando(Integer.parseInt(operandos[0]));
Operando operando2 = new Operando(Integer.parseInt(operandos[1]));
switch (tipoOperacion) {
case SUMA:
operacion = new InteractorSuma(operando1, operando2);
break;
case RESTA:
operacion = new InteractorResta(operando1, operando2);
break;
case MULT:
operacion = new InteractorMultiplicacion(operando1, operando2);
break;
case DIV:
operacion = new InteractorDivision(operando1, operando2);
break;
}
operacion.calcular();
vista.mostrarResultado(String.valueOf(operacion.getResultado().getValor()));
}
Return 子实例 class,而不是父实例 class。
@Module
public class InteractorModule {
@Provides
public InteractorSuma provideSuma() {
return new InteractorSuma();
}
@Provides
public InteractorResta provideResta() {
return new InteractorResta();
}
@Provides
public InteractorDivision provideDiv() {
return new InteractorDivision();
}
@Provides
public InteractorMultiplicacion provideMult() {
return new InteractorMultiplicacion();
}
}
您应该将 one-other 与 @Named("someName")
注释分开,或者您可以按照@Derek 所说的进行操作。我的做法:
@Provides
@Named("someName1")
public Operacion provideSuma() {
return new InteractorSuma();
}
@Provides
@Named("someName2")
public Operacion provideResta() {
return new InteractorResta();
}
@Provides
@Named("someName3")
public Operacion provideDiv() {
return new InteractorDivision();
}
@Provides
@Named("someName4")
public Operacion provideMult() {
return new InteractorMultiplicacion();
}
不然dagger不知道哪一个到return哪里。
注入时也调用@Named
。
对于这种情况,Dagger2 Qualifiers
就是为这种情况而构建的。
1.- 创建您的预选赛:
@Qualifier
public @interface OperacionSuma {}
@Qualifier
public @interface OperacionResta {}
@Qualifier
public @interface OperacionDiv {}
@Qualifier
public @interface OperacionMult {}
2.- 在您的提供者方法中设置限定符:
@Module
public class InteractorModule {
@Provides
@OperacionSuma
public Operacion provideSuma() {
return new InteractorSuma();
}
@Provides
@OperacionResta
public Operacion provideResta() {
return new InteractorResta();
}
@Provides
@OperacionDiv
public Operacion provideDiv() {
return new InteractorDivision();
}
@Provides
@OperacionMult
public Operacion provideMult() {
return new InteractorMultiplicacion();
}
}
3.- 指定您想在演示者中注入哪种 "operation":
class Presenter {
@Inject
Presenter(@OperacionSuma Operacion operacion) { }
@Inject
Presenter(@OperacionResta Operacion operacion) { }
@Inject
Presenter(@OperacionDiv Operacion operacion) { }
@Inject
Presenter(@OperacionMult Operacion operacion) { }
}
由于 dagger 查找 return 类型,而不是为函数指定的名称,因此您应该注意它。但是,Dagger2 提供了解决此类问题的方法。使用@Named 注解。
Sometimes the type alone is insufficient to identify a dependency. For example, if you need a Refrofit instance with GsonConverterFactory and another one ScalarConverterFactory you will end up with 2 provide methods that have the same return type: Retrofit. In this case, you can use @Named annotation to differentiate two Retrofit instances
现在可以像下面这样使用了
来处理你的情况
@Module
public class InteractorModule {
@Provides
@Named("InteractorSuma")
public Operacion provideSuma() {
return new InteractorSuma();
}
@Provides
@Named("InteractorResta")
public Operacion provideResta() {
return new InteractorResta();
}
@Provides
@Named("InteractorDivision")
public Operacion provideDiv() {
return new InteractorDivision();
}
@Provides
@Named("InteractorMultiplicacion")
public Operacion provideMult() {
return new InteractorMultiplicacion();
}
}
Here is 如何使用 @Named
注释的完整示例
如果您还有问题,请告诉我