【问题标题】:Playframework plugins and genericsPlayframework 插件和泛型
【发布时间】:2014-01-17 22:58:48
【问题描述】:

我想实现这样的情况:带有泛型参数的抽象类和实现该类的具体插件。

例如:

abstract class BasePlugin[T] extends Plugin {
  def d: T
}

class MyPlugin(app: Application) extends BasePlugin[String] {
  val d = "test" 
}

我的愿望是实现以下目标:

val plugin = app.plugin[BasePlugin[String]]
//Ok, plugin = Some(MyPlugin)

val plugin = app.plugin[BasePlugin[Int]]
//KO, plugin = None

当然这不会发生,因为 myPlugin 使用任何类型作为参数(类型擦除?)。 无论如何,找到一种获得上述内容的技术对我来说是非常有效的。有什么想法吗?

【问题讨论】:

  • Scala 有一个叫做 ClassTag 的东西,它可以在应用程序编译后保留类型信息。在 scala 2.10 之前它被称为 Manifest。也许您可以使用它们来解决问题?!

标签: scala generics playframework scala-2.10


【解决方案1】:

播放插件 api 在查找属于 Java 的插件时使用 Class.isAssignableFrom,因此 Scala 获得 ClassTag/TypeTags 无济于事。

也许您可以创建自己的子插件格式,例如:

trait SubPlugin[T] {
  def doSomething(t: T) {}
}

trait MetaPlugin {

  private val subPlugins: Seq[(Class[_], SubPlugin[_])] = ???

  def subPlugin[T](implicit classTag: ClassTag[T]): Option[SubPlugin[T]] = {
    subPlugins.collectFirst {
      case (c, p) if c.isAssignableFrom(classTag.runtimeClass) => p.asInstanceOf[SubPlugin[T]]
    }
  }
}

object MetaPlugin {

  def apply[T](implicit app: play.api.Application, classTag: ClassTag[T]): Option[SubPlugin[T]] =
    app.plugin[MetaPlugin].flatMap(_.subPlugin[T])

}


object AndThenSomeWhere {
  import play.api.Play.current
  MetaPlugin[String].map(_.doSomething("a string"))
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 1970-01-01
    相关资源
    最近更新 更多