Кинжал: свойство lateinit не было инициализировано - PullRequest
1 голос
/ 27 сентября 2019

В этом вопросе уже есть несколько тестов, но мне кажется, что они говорят о разных вещах (в большинстве случаев Android Kotlin + Dagger2), а не о моем конкретном случае.

Я учусьКинжал, прочитав это сообщение в блоге .Вместо этого, используя код Java из этого блога, я пытаюсь использовать Kotlin.

Итак, House.kt в качестве интерфейса:

interface House {
    fun prepareForWar()
    fun reportForWar()
}

Как есть BoltonsDagger.kt:

class BoltonsDagger @Inject constructor(): House {
    override fun reportForWar() {
        println("${this.javaClass.simpleName} reporting..")
    }

    override fun prepareForWar() {
        println("${this.javaClass.simpleName} prepared for war")
    }
}

Как есть StarksDagger.kt:

class StarksDagger @Inject constructor(): House {
    override fun prepareForWar() {
        println("${this.javaClass.simpleName} prepared for war")
    }

    override fun reportForWar() {
        println("${this.javaClass.simpleName} reporting..")
    }
}

Наконец WarDagger.kt с функцией main:

class WarDagger @Inject constructor() {
    @Inject lateinit var starks: StarksDagger
    @Inject lateinit var boltons:BoltonsDagger

    fun prepare() {
        starks.prepareForWar()
        boltons.prepareForWar()
    }

    fun report() {
        starks.reportForWar()
        boltons.reportForWar()
    }
}

fun main() {
    val war = WarDagger()
    war.prepare()
    war.report()
}

С ошибкой: Exception in thread "main" kotlin.UninitializedPropertyAccessException: lateinit property starks has not been initialized.

1 Ответ

2 голосов
/ 27 сентября 2019

Во-первых, измените WarDagger на следующее:

class WarDagger @Inject constructor(
    private val starks: StarksDagger,
    private val boltons: BoltonsDagger
) {
    ...
}

Этим вы даете понять Dagger, как должен создаваться экземпляр WarDagger.Нет необходимости аннотировать поля конструктора с помощью @Inject.

Я не могу найти компонент кинжала в вопросе, поэтому давайте создадим его:

@Component
interface WarComponent {
    fun provideWarDagger(): WarDagger
}

Мы создаем экземпляр WarDagger доступны через компонент, так что клиенты могут получить его экземпляр.

Теперь внутри main вместо того, чтобы вручную создавать экземпляр WarDagger, вы должны извлекать его из компонента кинжала, потому что этовся причина, по которой вы используете DI-фреймворк, не так ли?Клиенты не должны знать, как создаются зависимости:

fun main() {
    val component = DaggerWarComponent.create()
    val war = component.provideWarDagger()
    war.prepare()
    war.report()
}
...