В Dagger2 создание карты конкретных экземпляров завершается неудачно с «невозможно предоставить без аннотации @ Provides» - PullRequest
0 голосов
/ 23 сентября 2019

Я играю с коллекцией Dagger, в частности с картой.

Я хочу использовать Dagger2 для добавления карты, ключ которой является перечислением, а значения - конкретной реализацией интерфейса.Карта вводится в презентере.Уникальный компонент создает экземпляр презентатора, действие использует его создание для отображения строк, созданных значением карты.

Я получаю следующую ошибку:

e: ../DaggerMap/app/build/tmp/kapt3/stubs/debug/com/aklal/briquedagger2/MainComponent.java:7: error: [Dagger/MissingBinding] java.util.Map<com.aklal.briquedagger2.Lapse.TIME,? extends com.aklal.briquedagger2.Lapse.ChristmasTime> cannot be provided without an @Provides-annotated method.
public abstract interface MainComponent {
                ^
      java.util.Map<com.aklal.briquedagger2.Lapse.TIME,? extends com.aklal.briquedagger2.Lapse.ChristmasTime> is injected at
          com.aklal.briquedagger2.MainPresenter(mapOfLapse)
      com.aklal.briquedagger2.MainPresenter is injected at
          com.aklal.briquedagger2.MainModule.getMainPresenter(connection)
      com.aklal.briquedagger2.Presenter is provided at
          com.aklal.briquedagger2.MainComponent.presenter()

FAILURE: Build failed with an exception.

«Проект» может здесь

Реализация

У меня есть интерфейс ChristmasTime, который реализуется двумя классами:

  • TimeUntilNextChristmas
  • TimeSinceLastChristmas

Эта реализация аналогично просто определяется следующим образом:

class TimeSinceLastChristmas @Inject constructor(): ChristmasTime {
    override fun getLapseOfTime() = "SINCE TEST"
}    

Я хочу позволить Dagger2 создать карту с

  • значение enum как ключ
  • ChristmasTime как значение типа

Значение ключа определяется следующим образом:

@MapKey
annotation class TimeKey(val value: TIME)

enum class TIME {
    UNTIL,
    SINCE
}

Я создал модуль дляпредоставить конкретные реализации типа ChristmasTime:

@Module
interface LapseOfTimeModule {
    @Binds
    @IntoMap
    @TimeKey(TIME.UNTIL)
    fun provideLapsesOfTimeUntil(t: TimeUntilNextChristmas): ChristmasTime

    @Binds
    @IntoMap
    @TimeKey(TIME.SINCE)
    fun provideLapsesOfTimeSince(t: TimeSinceLastChristmas): ChristmasTime
}

Я хочу, чтобы строка, возвращенная конкретными реализациями, отображалась на экране.Для этого докладчик связывается с действием строк, содержащихся в карте (которая была введена в презентатор):

class MainPresenter @Inject constructor(
    private val mapOfLapse: Map<TIME, ChristmasTime>
) : Presenter {
    override fun getDateUntil(): String = mapOfLapse[TIME.UNTIL]?.getLapseOfTime() ?: "UNTIL FAILED"
}

Компонент для создания экземпляра презентатора в MainActivity принимает модуль, который определяеткарта (LapseOfTimeModule) и MainModule

@Component(modules = [MainModule::class, LapseOfTimeModule::class])
interface MainComponent {
    fun presenter(): Presenter
}

MainModule это:

@Module
interface MainModule {
    @Binds
    fun getMainPresenter(connection: MainPresenter): Presenter
}

И MainActivity это:

class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var presenter: Presenter


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        presenter = DaggerMainComponent.create().presenter()

        bttDisplayNewDate.setOnClickListener{
            displayDate(
                presenter.getDateSince(),
                presenter.getDateUntil()
            )
        }
    }

    fun displayDate(since: String, until: String) {
        tvSince.text = since
        tvUntil.text = until
    }
}

Кто-нибудь знает, как это исправить?

Вот некоторые темы, которые я прочитал, но они не сильно помогли:

Заранее спасибо !!

ps: используется версия кинжала 2.24 и версия kotlin1.3.41

...