【问题标题】:Scala - Using guice multibinder on a generic interface failsScala - 在通用接口上使用 guice multibinder 失败
【发布时间】:2015-11-12 17:45:54
【问题描述】:

我有如下界面:

trait Subject[T] {
   def fetch() :Future[Option[T]]
}

和类:

class ChildSubject@Inject()(dao:Dao) extends Subject[String]{
   def fetch(): Future[Option[String]] ={
       dao.find("10").map{ name => Some(name) 
   }     
}

还有一个模块:

class SubjectModule extends AbstractModule with ScalaModule{
    override def configure(): Unit = {
          val subMulti = ScalaMultibinder.newSetBinder[Subject](binder)
          subMulti.addBinding.to[ChildSubject]
    }
}

我尝试注入这个 Set:

@Singleton
class SomeClass @Inject()(subjects: Set[Subject]){
    subjects.map{
      //do somthing
    }
}

我收到以下错误:

play.sbt.PlayExceptions$CompilationException: Compilation error[kinds    
of the type arguments (com.test.Subject) do not conform to the expected  
kinds of the type parameters (type T).
com.test.Subject's type parameters do not match type T's expected  
parameters:
trait Subject has one type parameter, but type T has none]

有什么想法吗?? 谢谢!

【问题讨论】:

    标签: scala playframework playframework-2.0 guice


    【解决方案1】:

    你需要一个 new TypeLiteral<Subject<String>>() 来绑定 - 像 Java 中的 Guice 中的 Subject<T> 这样的通用类型接口。 Scala 很可能需要某种形式的相同。

    这样的事情可能会奏效:

    class SubjectModule extends AbstractModule with ScalaModule{
      override def configure(): Unit = {
        val subMulti = ScalaMultibinder.newSetBinder[Subject[String]](binder)
        subMulti.addBinding.to[ChildSubject]
      }
    }
    

    【讨论】:

    • 问题是我可能有几个不同类型的类,例如:ChildOne 扩展了 Subject[Int],而 ChildTwo 扩展了 Subject[String],所以我不能将它专门绑定到 String。有意义吗?
    • @Tomer 是的。我知道你要去哪里。您需要 multibinder 在 addBinding 步骤中提供类型参数,但如何?嗯
    • 您需要能够部分应用类型构造函数。我知道在 Haskell 中。不知道如何在 Scala 中做到这一点。
    • 您希望绑定集具有什么类型?
    • @TavianBarnes 我希望它是 Set[Subject]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-16
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多