2017-06-16 6 views
0

私はGuice依存関係注入でPlay 2.5を使用しています。私は今だけclassNameは設定で指定されたクラスをバインドできるようにする必要があり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は、誰もがGuiceのを経由して、それをバインドする方法についてのアイデアを持っていそうでなければ、私は

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

のようなものを使用しているだろう、注入される必要がある引数を持っているので、それは、Guiceのを介して行われる必要があります?

+0

あなたはそれが正しいジェネリック型であることをキャストすることができませんか?私はScalaを知らないが、Javaクラス ' clazz =(Class )Class.forName(className);である。 bind(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's 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])) 
関連する問題