为什么不能要求requestInjection在Kotlin对象上工作

时间:2019-04-16 13:18:45

标签: kotlin guice

我是Guice的新手。我正在尝试使用requestInjection以这种方式注入kotlin单例对象的依赖项。

方法1

class SampleTest {

    @Test
    fun test() {
        Guice.createInjector(object: KotlinModule() {
            override fun configure() {
                requestInjection(A)
            }
        })
        assertEquals("Hello world", A.saySomething())
    }
}

object A {
    @Inject
    private lateinit var b: B

    fun saySomething(): String {
        return b.sayHello()
    }
}

class B {
    fun sayHello(): String {
        return "Hello world"
    }
}

但是我收到此错误:

kotlin.UninitializedPropertyAccessException: lateinit property b has not been initialized

如果我将A更改为带有无参数构造函数的类,那么它将起作用。

方法2

class SampleTest {

    @Test
    fun test() {
        val a = A()
        Guice.createInjector(object: KotlinModule() {
            override fun configure() {
                requestInjection(a)
            }
        })
        assertEquals("Hello world", a.saySomething())
    }
}

class A {
    @Inject
    private lateinit var b: B

    fun saySomething(): String {
        return b.sayHello()
    }
}

class B {
    fun sayHello(): String {
        return "Hello world"
    }
}

相反,如果我将 requestInjection 更改为 requestStaticInjection ,它也可以工作。

方法3

class SampleTest {

    @Test
    fun test() {
        Guice.createInjector(object: KotlinModule() {
            override fun configure() {
                requestStaticInjection<A>()
            }
        })
        assertEquals("Hello world", A.saySomething())
    }
}

object A {
    @Inject
    private lateinit var b: B

    fun saySomething(): String {
        return b.sayHello()
    }
}

class B {
    fun sayHello(): String {
        return "Hello world"
    }
}

APPROACH 1 为什么不起作用? APPROACH 2 APPROACH 3 为什么起作用?

1 个答案:

答案 0 :(得分:0)

Kotlin's objects are treated as language static singletons, i.e. their initialization/instantiations happens outside the scope of the dependency injection framework.

Therefor, when using the KotlinModule to inject an object, you have to use requestStaticInjection like in APPROACH 3, or change that object to a class, so that the Guice KotlinModule sees it as non-static, as presented in APPROACH 2

Hope that clarifies things a bit.