使用Guice + Kotlin绑定对象列表 [英] Bind list of objects using Guice + Kotlin

查看:167
本文介绍了使用Guice + Kotlin绑定对象列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a JavaFX application in Kotlin with the following controller definition:

class MainController {

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

}

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

I'm using Guice for Dependency management. And I'm trying to inject the list of class instances loaded via java.util.ServiceLoader. My problem is to define a binding that will inject the list of loaded object instances into the declared field. I tried annotation based provisioning:

internal class MyModule: AbstractModule() {

    override fun configure() { }

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

}

和多绑定扩展名(在corse的字段定义中将列表"切换为设置")

and multibinding extension (switched List to Set in field definition of corse):

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)
        }
    }

}

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

but both of these approaches leads to the same error:

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会知道要向该字段中注入什么内容.

I'm starting to suspect that it somehow related to Kotlin gerenic variance and Guice strict type checking. But I don't know how to declare the binding so Guice will know what to inject into this field.

推荐答案

是的,它是由于差异而发生的,但是有一种方法可以使它起作用.

Yes, it happens because of variance but there's a way to make it work.

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

默认情况下,Kotlin为componentDescriptors字段生成List<? extends ComponentDescriptor>签名. @JvmSuppressWildcards使其生成简单的参数化签名List<ComponentDescriptor>.

By default Kotlin generates List<? extends ComponentDescriptor> signature for the componentDescriptors field. The @JvmSuppressWildcards makes it generate a simple parameterized signature List<ComponentDescriptor>.

这篇关于使用Guice + Kotlin绑定对象列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆