javaandroiddagger-2mvp

Dagger2 Error at inject in a class who injects


I'm trying to inject in my presenter an interactor but gives me an error, at seems I can't inject in a class who injects to another:

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)

This is my InteractorModule who provides me a 4 classes depending which I want to use and where seems is the problem:

@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();
    }
}

I want to inject here instead of init the new items:

@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()));
}

Solution

  • You should separate one-other with the @Named("someName") annotation, or you could just do what @Derek says. My approach:

    @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();
        }
    

    Otherwise dagger doesn't know which one to return where.

    Call the @Named when injecting also.