2017-06-16 84 views
0

我正在使用Play 2.5與Guice依賴注入。如何使用FQDN字符串將Google Guice綁定到類

正常綁定的工作原理是:

bind(classOf[SomeClass]).to(classOf[DefaultClass]) 

我現在只需要能夠綁定在類名已在配置中指定的類。

我想是這樣的:

val className = config.getString("someClass.className") 
val x: Class[_] = Class.forName(className) 
bind(classOf[SomeClass]).to(classOf[x]) 

但隨後的類型是錯誤的。

它需要通過吉斯做,因爲SomeClass具有需要被注入一個說法,否則我會用類似

val className = config.getString("someClass.className") 
val x = Class.forName(className).newInstance().asInstanceOf[SomeClass] 
bind(classOf[SomeClass]).toInstance(x) 

有誰知道如何將它通過吉斯綁定的想法?

+0

你不能投它是正確的泛型類型?我不知道斯卡拉,但在Java'類 clazz =(Class )Class.forName(className);綁定(SomeClass.class).to(clazz);' –

回答

0

我認爲你正在尋找這樣的事情...

lazy val injector = (new GuiceApplicationBuilder).injector() 
def inject[T : ClassTag]: T = { 
    injector.instanceOf[T] 
} 

這是最簡單的版本,但不處理參數。您將創建一個班級,然後將其稱爲inject[SomeDep]

我還沒有找到一種很好的注入方式,這是真正通過最頂層被調用類中的@inject進行注入的唯一方法。目前我們只使用注入進行單元測試。

+0

他並不是想動態注入,而是設置一個可以在運行時指定的綁定。 –

0

感謝您的回覆,但我終於使用了Scala的Reflection。使用

object Reflection { 
    import scala.reflect.api 
    import reflect.runtime.universe._ 
    import reflect.ClassTag 

    def classTagToClass[T: reflect.ClassTag]: Class[T] = { 
    def ctag = implicitly[reflect.ClassTag[T]] 
    ctag.runtimeClass.asInstanceOf[Class[T]] 
    } 

    def typeToClassTag[T: TypeTag]: ClassTag[T] = { 
    ClassTag[T](typeTag[T].mirror.runtimeClass(typeTag[T].tpe)) 
    } 

    def stringToTypeTag[A](name: String): TypeTag[A] = { 
    val c = Class.forName(name) // obtain java.lang.Class object from a string 
    val mirror = runtimeMirror(c.getClassLoader) // obtain runtime mirror 
    val sym = mirror.staticClass(name) // obtain class symbol for `c` 
    val tpe = sym.selfType // obtain type object for `c` 
    // create a type tag which contains above type object 
    TypeTag(mirror, new api.TypeCreator { 
     def apply[U <: api.Universe with Singleton](m: api.Mirror[U]): U#Type = 
     if (m eq mirror) { 
      tpe.asInstanceOf[U#Type] 
     } 
     else { 
      throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.") 
     } 
    }) 
    } 
} 

上述目的,您可以通過以下方式使用它FQDN綁定類:

configuration.getString("config.className") 
.map(className => 
    bind(classOf[AbstractClass]).to(classTagToClass(typeToClassTag(stringToTypeTag[AbstractClass](className)))) 
).getOrElse(bind(classOf[AbstractClass]).to(classOf[AbstractClassImpl]))