使用 Guice + Kotlin 绑定对象列表

2024-06-21

我正在 Kotlin 中使用以下控制器定义编写 JavaFX 应用程序:

class MainController {

    @Inject private lateinit var componentDescriptors: List<ComponentDescriptor>
    /* More code goes here */

}

我正在使用 Guice 进行依赖管理。我正在尝试注入通过加载的类实例列表java.util.ServiceLoader。我的问题是定义一个绑定,将加载的对象实例列表注入到声明的字段中。我尝试了基于注释的配置:

internal class MyModule: AbstractModule() {

    override fun configure() { }

    @Provides @Singleton
    fun bindComponentDescriptors(): List<ComponentDescriptor> = 
            ServiceLoader.load(ComponentDescriptor::class.java).toList()

}

和多重绑定扩展(在 corse 的字段定义中将 List 切换为 Set):

internal class MyModule: AbstractModule() {

    override fun configure() {
        val componentDescriptorBinder = Multibinder.newSetBinder(binder(), ComponentDescriptor::class.java)
        ServiceLoader.load(ComponentDescriptor::class.java).forEach {
            componentDescriptorBinder.addBinding().toInstance(it)
        }
    }

}

但这两种方法都会导致相同的错误:

No implementation for java.util.List<? extends simpleApp.ComponentDescriptor> was bound.
  while locating java.util.List<? extends simpleApp.ComponentDescriptor>
    for field at simpleApp.MainController.componentDescryptors(MainController.kt:6)
  while locating simpleApp.MainController

1 error
    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1042)
    at com.google.inject.internal.InjectorImpl.getProvider(InjectorImpl.java:1001)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051)
    at com.gluonhq.ignite.guice.GuiceContext.getInstance(GuiceContext.java:46)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:929)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
    ... 12 more

我开始怀疑它在某种程度上与 Kotlin gerenic 方差和 Guice 严格类型检查有关。但我不知道如何声明绑定,以便 Guice 知道要向该字段中注入什么。


是的,这是由于差异而发生的,但有一种方法可以让它发挥作用。

class MainController {
    @JvmSuppressWildcards
    @Inject
    private lateinit var componentDescriptors: List<ComponentDescriptor>    
}

默认情况下 Kotlin 生成List<? extends ComponentDescriptor>的签名componentDescriptors场地。这@JvmSuppressWildcards使它生成一个简单的参数化签名List<ComponentDescriptor>.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Guice + Kotlin 绑定对象列表 的相关文章

随机推荐