【问题标题】:Generic Guice Module通用 Guice 模块
【发布时间】:2021-08-05 07:09:49
【问题描述】:

是否可以定义一个通用的 Guice-Module?

我总是收到CreationException

Exception in thread "main" com.google.inject.CreationException: Unable to create injector, see the following errors:

1) com.example.test.GenericClass<T> cannot be used as a key; It is not fully specified.

1 error
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:470)
    at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
    at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
    at com.google.inject.Guice.createInjector(Guice.java:99)
    at com.google.inject.Guice.createInjector(Guice.java:73)
    at com.google.inject.Guice.createInjector(Guice.java:62)
    at com.example.test.GenericModuleKt.main(genericModule.kt:23)
    at com.example.test.GenericModuleKt.main(genericModule.kt)

这是我的示例代码:

package com.example.test

import com.google.inject.AbstractModule
import com.google.inject.Guice
import com.google.inject.Key
import com.google.inject.TypeLiteral

class SomeClass

class GenericClass<T>

class GenericModule<T> : AbstractModule() {
    override fun configure() {
        bind(object : TypeLiteral<GenericClass<T>>(){})
    }
}

fun main() {
    val injector = Guice.createInjector(
        GenericModule<SomeClass>()
    )

    val instance : GenericClass<SomeClass> =
        injector.getInstance(object : Key<GenericClass<SomeClass>>(){})
}

编辑:在 Yurii Melnychuk 的帮助下的工作示例

需要使用Types.newParameterizedType来指定泛型类:

class SomeClass

class GenericClass<T>

class GenericModule(
    private val genericClass: Class<*>
) : AbstractModule() {
    override fun configure() {
        val paraType = Types.newParameterizedType(GenericClass::class.java, genericClass)
        bind(TypeLiteral.get(paraType))
    }
}

fun main() {
    val injector = Guice.createInjector(
        GenericModule(SomeClass::class.java)
    )

    val instance : GenericClass<SomeClass> =
        injector.getInstance(object : Key<GenericClass<SomeClass>>(){})
}

如果遇到任何问题(尤其是在使用泛型接口时),请尝试使用 Java 而不是 Kotlin。这为我解决了一些问题。

【问题讨论】:

    标签: java kotlin dependency-injection guice


    【解决方案1】:

    泛型类型信息在运行时被删除,所以不可能按照你想要的方式做你想做的事(至少在 Java 中,Kotlin 在这方面可能不同,但我不熟悉它,也许 reified 泛型可以帮助)。

    但从 Java 的角度来看,我宁愿将 TypeLiteral/Type 作为构造函数参数传递给模块并绑定它(com.google.inject.util.Types#newParameterizedType 应该会有所帮助)。

    【讨论】:

    • 感谢您的帮助。我有我的例子工作。我已将工作代码添加到问题中。不幸的是,我在现实生活中的例子有点复杂。我有一个由该通用类实现的通用接口。似乎我无法将 ParameterizedType-Interface 绑定到 ParameterizedType-Class。它抛出一个异常,即没有绑定接口的实现,尽管这正是我所做的。我在最初的问题中添加了一个示例。
    • 更新:我似乎这只是使用 kotlin 时的一个问题。在 Java 中,一切都按预期工作。
    猜你喜欢
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 2017-05-31
    相关资源
    最近更新 更多