2017-06-16 81 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]))