2016-01-19 9 views
6

Play Framework 2.4でGuice InjectorクラスのgetInstanceメソッドを使用したいのですが、どうすればアクセスできますか?Play Framework 2.4 guice Injectorにアクセスするには?

実行時に別のファクトリを返すファクトリを実装するためにGuice FactoryModuleBuilderを使用しました。ファクトリーを返す第2レベルでは、@Injectアノテーションの代わりにリフレクションを使用してオブジェクトを手動で取得するためにPlay Guice Injectorにアクセスする必要があります。

+0

もっと詳しく教えてください。なぜインジェクタにアクセスする必要がありますか? – marcospereira

+0

@marcospereira私はGuice FactoryModuleBuilderを使用して、実行時に別のファクトリを返すファクトリを実装しました!返す工場の第2レベルでは、私はPlay guice Injectorにアクセスして、Injectアノテーションの代わりにリフレクションを使ってオブジェクトを手動で取得する必要があります。 –

+0

'Play.current'はある時点で削除されるため、使用しないでください。注射器を注射できるのでしょうか? – marcospereira

答えて

12

多くの方法があります。私はこれを使います。

編集:あるバージョンの

Play.maybeApplication.map(_.injector.instanceOf[MyProdClass]).getOrElse(new MyDevClass) 

または

Play.current.injector.instanceOf[MyClass] 

> = 2.5::これは< = 2.4ですプレイのバージョンに関連する

import play.api.inject.Injector 
import javax.inject.Inject 

class MyService @Inject() (injector: Injector) ={ 
    val myClassInstance = injector.instanceOf[MyClass] 
    //do stuff 
} 
+0

技術的には間違いありませんが、インジェクタが静的に(生産的なシステムで)アクセスされると、最初のアプローチは間違ったインスタンスにつながります。これは起こるべきではありません - もちろん、2番目のアプローチは少なくともそれについては明らかです。異なるバインディングを使用する場合は、開発環境で別のアプリケーションローダーを使用する必要があります。 – rethab

+1

他のすべての静的アクセサと同様に、Play.currentは非推奨です。古い静的アプローチの代わりにDIを使用する必要があります。 – Serg

+0

最初のアプローチはどのように機能しますか?このアプリケーションはどのように作成されますか?私はインサイダーがGlobal.scalaの内部で定義されているPlay 2.3アプリケーションにGuice Injectionを導入しようとしていますか?これはうまくいきますが、@Inject表記を使わずにインジェクタにアクセスするにはまともな方法がありません。 – Serendipity

4

ことがありますGuice Injectorを注入する方が良い:

@Inject 
private Injector injector; 

それとも、プレイフレームワークのJava版のため、このコードを使用することができます。

Play.application().injector().instanceOf(YourClass.class); 
5

プレイFrameworkの2.5.xのplay.api.Play.currentで廃止されており、DIは常に優先されなければなりません。したがって、インジェクタのインスタンスを取得するための適切な方法を使用することです:

import play.api.inject.Injector 
import javax.inject.Inject 

class SomeClassRequiringInjector @Inject() (injector: Injector) { ... } 

DIプロバイダクラスでこれを行う場合でも:)

+1

では、このタイプの注入は機能しません。何か案が? –

+1

Javaの@SimonFakirでは、play.inject.Injectorを挿入する必要があります。なぜなら、play.api。*の下にあるものはすべてScala用であるからです。 – Serg

+0

@エグレアレ、あなたの答えは受け入れるべきだと思います!また、play.inject.Injectorを注入する必要のあるJavaの例も含めるとよいでしょう。 – Serg

3

を離れて他のプレイ2.5.xのソリューションから、状況があるかもしれない私の作品注入を使わずにオブジェクトにインジェクタを入れたいと思っています。たとえば、Scalaシングルトンを使用している場合、@injectはおそらく動作しません。それ以外の場合は、自動的に初期化されることはありません、熱心にシングルトンを設定するにはGuiceのモジュールで

@Singleton 
class GlobalContext @Inject()(injector: Injector) { 
    GlobalContext.injector = injector 
} 

object GlobalContext { 
    private var injector: Injector = null 
} 

:その場合は

、あなたはこれを使用することができます

// Module.scala 
class Module extends AbstractModule { 
    override def configure() = { 
    // ... 

    // Eager initialize Context singleton 
    bind(classOf[GlobalContext]).asEagerSingleton() 
    } 
} 
0

私は本当に好きDevabc's solutionインジェクタ自体を取得するためにコンストラクタインジェクションに依存できないシナリオがいくつかあるため、Play 2.5.xでは、非推奨のplay.api.Play.current.Injectorコードを使用してインジェクタを取得する必要があります。

彼のソリューションは、Play組み込みインジェクタへの参照を作成し、それを必要なときに任意のコンポーネントによってインポートできるScalaオブジェクトに配置します。ブリリアント!

しかし、オブジェクトをインジェクタを取得するためのパブリックインターフェイスを提供する必要がありますので、修正するコードを修正し、使用方法をデモします。

import play.api.inject.Injector 
import javax.inject.Inject 

@Singleton 
class GlobalContext @Inject()(playInjector: Injector) { 
    GlobalContext.injectorRef = playInjector 
} 

object GlobalContext { 
    private var injectorRef: Injector = _ 

    def injector: Injector = injectorRef 
} 

初期化部分は同じです。

// InjectionModule.scala 
package modules 

class InjectionModule extends AbstractModule { 
    override def configure() = { 
    // ... 

    // Eager initialize Context singleton 
    bind(classOf[GlobalContext]).asEagerSingleton() 
    } 
} 

// application.conf 
play.modules.enabled += "modules.InjectionModule" 

クライアントコードは非常に簡単です。インジェクタを必要とするコンポーネントであれば、

// Import the object GlobalContext 
import GlobalContext.injector 

// ... 
val yourClassInstance = injector.instanceOf[YourClass] 
関連する問題