匕首:lateinit属性尚未初始化

时间:2019-09-27 06:54:36

标签: kotlin dependency-injection dagger-2 dependency-management dagger

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

我正在通过阅读this blog post来学习Dagger。而不是使用该博客中的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.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

1 个答案:

答案 0 :(得分:2)

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