1

I'm new in Dagger dependency injection. I have this interface implemented in two different classes:

interface TaskCardContract {
    interface View{
        fun setDescription(description: String)
        fun setSubTitle(subTitle: String)
        fun setIcon(iconId: Int)
        fun setAction(actionToExecute: () -> Unit)
        fun configureUi()
    }

    interface Presenter{
        fun attachView(view: android.view.View)
        fun setAction(actionToExecute: () -> Unit)
        fun executeAction()
    }
}

These are the classes:

class TaskCardPresenter : TaskCardContract.Presenter {
    private lateinit var taskCard: TaskCard
    private var taskAction: (() -> Unit)? = null

    override fun setAction(actionToExecute: () -> Unit) {
        ...
    }

    override fun executeAction() {
        ...
    }

    override fun attachView(view: android.view.View){
        ...
    }
}

class TaskReservationCardPresenter : TaskCardContract.Presenter {
    private lateinit var taskCard: TaskReservationCard
    private var taskAction: (() -> Unit)? = null

    override fun setAction(actionToExecute: () -> Unit) {
        ...
    }

    override fun executeAction() {
        ...
    }

    override fun attachView(view: android.view.View){
        ...
    }
}

Reading this post I inserted @Named tag in both implementations of my module and in classes when they are injected:

open class TaskCard : ConstraintLayout, TaskCardContract.View{
    @Inject
    @Named("TaskCardViewPresenter")
    lateinit var presenter: TaskCardContract.Presenter
    ...
}

class TaskReservationCard : ConstraintLayout, TaskCardContract.View {
    ...
    private var reservationHandler: ReservationHandler? = null

    @Inject
    @Named("TaskReservationCardPresenter")
    lateinit var reservationPresenter: TaskCardContract.Presenter
    ...
}

@Module
class ViewModule(private val view: View){
    ...
    @Provides
    @Named("TaskCardViewPresenter")
    fun providesTaskCardViewPresenter() : TaskCardContract.Presenter = TaskCardPresenter()

    @Provides
    @Named("TaskReservationCardPresenter")
    fun providesTaskReservationCardPresenter() : TaskCardContract.Presenter = TaskReservationCardPresenter()
    ...
}

And this is when they are declare for injection. The ViewModule is a Subcomponent:

@Subcomponent(modules = [ViewModule::class])
interface ViewComponent {
    fun inject(taskCard: TaskCard)
    fun inject(taskReservationCard: TaskReservationCard)
    ...
}

Even with the @Named tag, Dagger complains about @Provides tag. Log information:

error: [com.di.ViewComponent.inject(com.ui.taskcard.TaskCard)] com.ui.taskcard.TaskCardContract.Presenter cannot be provided without an @Provides- or @Produces-annotated method.
public abstract interface AppComponent {
                ^
      com.ui.taskcard.TaskCardContract.Presenter is injected at
          com.ui.taskcard.TaskCard.presenter

What do I need to do to Dagger injects both implementations?

learner
  • 1,311
  • 3
  • 18
  • 39

1 Answers1

0

After digging for more answers, I found out kotlin needs to do named injection in a different way:

@field:[Inject Named("TaskReservationCardPresenter")]
    lateinit var reservationPresenter: TaskCardContract.Presenter

@field:[Inject Named("TaskCardViewPresenter")]
    lateinit var presenter: TaskCardContract.Presenter

This solves the problem. Refer to this link.

learner
  • 1,311
  • 3
  • 18
  • 39