Dagger: lateinit 属性 尚未初始化

Dagger: lateinit property has not been initialized

关于这个问题已经有几个 QA,但对我来说,他们似乎在谈论不同的事情(Android 的 Kotlin + Dagger2,在大多数情况下)并且没有应用我的具体案例。

我正在通过阅读 this blog post 来学习 Dagger。我正在尝试使用 Kotlin,而不是使用该博客中的 Java 代码。

因此,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.ktmain 函数:

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.

首先,将 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()
}