2014-01-17 5 views
0

Я хотел бы реализовать такую ​​ситуацию: абстрактный класс с общим параметром и конкретным плагином, который реализует этот класс.Плагины и генерические файлы для плагинов

, например:

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 встречается с использованием любого типа в качестве параметра (типа стирания?). В любом случае для меня было бы очень полезно найти технику для получения вышеизложенного. Есть идеи?

+0

Scala есть нечто, называемое ClassTag, это дает возможность сохранять информацию о типе, даже если приложение компилируется. Он назывался манифест перед скалой 2.10. Может быть, вы могли бы использовать их, чтобы обойти проблему ?! –

ответ

1

Плагин для игры api использует Class.isAssignableFrom, когда он ищет плагины, которые являются частью Java, поэтому это не поможет 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")) 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^