2016-06-02 4 views
0

私はコントローラクラスで依存関係注入を使用してインスタンス化しました。他の場所で@injectアノテーションを使用してそのオブジェクトを使用しようとすると、null値が返されます。ここに私のコードスケルトンがあります。@Injectオブジェクトnull:プレイ依存性注入

@singleton 
class ServiceClient(ws: WSClient, config: Configuration) { 
def get response() {...} 
} 

class App @Inject()(client: ServiceClient) extends Controller { 

    def getItems = Action { 
    Obj() 
    } 
} 

case class Obj() { 

    @Inject 
    var client: ServiceClient = _ 
    def doStuff() { 
    client.getResponse() //client is null so get null pointer exception. 
    .... 
    } 
} 

@Inject in Objは動作していないようです。私のクライアントオブジェクトは常にnullです。 (私はObjにパラメータとしてクライアントを渡したくありません)私の期待は、Obj()で注入されたはずのServiceClientオブジェクトです。私は何を間違えたのですか?コントローラにOBJに注入

更新

は、オプションではありません。 (私のアプリObjは、私のいくつかの複雑なルール、リフレクションを使用して実行時にインスタンス化されています)。また、Objにコンストラクタインジェクションをしたくないです。 私は、コントローラの外でServiceClientのフィールド注入を探しています。

アップデート2

私はOBJのクラスで

var client: ServiceClient = play.api.Play.current.injector.instanceOf(classOf[ServiceClient]) 

を使用して問題を解決することができました。 しかし、play.api.Play.currentはプレイ2.5で廃止されていますので、まだまだ警告が表示されています。

答えて

1

DIフレームワークを問い合せることなく、クラスインスタンスに依存性を注入することはできません。あなたのコードでは、手動でObjをインスタンス化します。これは依存性注入の魔法が起こっていないことを意味します。 Objクラスに依存性を注入するには、DIフレームワークでそのインスタンス化を処理する必要があります。あなたはここでできることは次のとおりです。

  1. を注入ServiceClientObjコンストラクタまたは提出のいずれかに:

    class Obj @Inject() (client: ServiceClient) { 
        // 
    } 
    

    ケースクラスは、より多くの「データ」のように聞こえるので、それは代わりにケースクラスの単純なクラスを使用するように理にかなっていますサービスやヘルパークラスではなく内部に不変のデータを持つクラスです。実際には、現在の定義はObjです。

  2. を注入Objおよび(または、必要に応じて)アプリのクラスにServiceClient

    class App @Inject()(obj: Obj, client: ServiceClient) extends Controller { 
        def getItems = Action { 
        obj.doStuff() 
        } 
    } 
    

は私がで使用される依存性注入とGuiceのフレームワークについての詳細を読むためにあなたをお勧めしますデフォルトで再生します。 Guice wiki

+0

ありがとうございました。クラスインスタンスへの依存性をどのように注入するのかについてもっと詳しく説明できますか? – konquestor

+0

フローは実際にDIフレームワークに依存します。 Guiceでは、共通パターンは1です。クラス(インタフェース)とその実装(バインディングは注釈を使用して行うこともできます)のバインディングを定義するモジュール(AbstractModuleを拡張するクラス)を定義します。2.そのモジュールのインジェクタを作成します。 Guice.createInjector(新しいYourModule()) '。 3.特定のクラスインスタンス 'injector.getInstance(classOf [Obj])'に対してインジェクタに問い合わせます。したがって、インスタンス化はGuiceによって処理されます。また、[DIのためのプレイ・ドキュメント](https://www.playframework.com/documentation/2.5.x/ScalaDependencyInjection)をご覧ください。 – yahor

+0

Playでは、通常、インジェクタは自分では作成しませんが、モジュールは一般的に使用されます。 Playコンフィグ( 'application.conf')のモジュールを有効にする必要があることに注意してください。 – yahor