Dagger2 Error at inject in a class who injects

橙三吉。 提交于 2020-06-29 03:41:55

问题


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

回答1:


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.




回答2:


For this kind of situation is where Dagger2 Qualifiers are build for.

1.- Create your qualifiers:

@Qualifier
public @interface OperacionSuma {}
@Qualifier
public @interface OperacionResta {}
@Qualifier
public @interface OperacionDiv {}
@Qualifier
public @interface OperacionMult {}

2.- Set qualifiers in your providers methods:

@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.- Specify what kind of "operation" do you want to inject in your presenter:

class Presenter {

    @Inject
    Presenter(@OperacionSuma Operacion operacion) { }

    @Inject
    Presenter(@OperacionResta Operacion operacion) { }

    @Inject
    Presenter(@OperacionDiv Operacion operacion) { }

    @Inject
    Presenter(@OperacionMult Operacion operacion) { }
}



回答3:


Since dagger looks for the return type, not a name that given to the function you should take care of it. However, Dagger2 provides a solution to such problems. Using @Named annotation.

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

Now you can use it like following

Coming to your case

@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 the full example of how to use @Named annotation

Let me know if you have still a problem




回答4:


Return the instance of Child class, not parent 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();
    }
} 


来源:https://stackoverflow.com/questions/56688817/dagger2-error-at-inject-in-a-class-who-injects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!