31

状況: 一部で遅延依存関係のインスタンス化が必要なため、コンストラクターのパラメーターとしてクラスにFooClass渡します。Injector

private final Injector m_injector;

public FooClass(@Named("FooInjector") Injector injector) {
m_injector = injector;
}

しかし、Guice はコア クラス (インジェクター、モジュールなど) をバインドすることを許可していません。解決策は何ですか?

4

4 に答える 4

28

Injectorを直接使用しないでください。代わりに を渡しProvider<FooClass>ます。また、使用する場所にプロバイダーを注入する必要がありますFooClass

private final Provider<FooClass> provider;

@Inject
public ClassWhereFooIsUsed(Provider<FooClass> provider) {
    this.provider = provider;
}

.... somewhere else
FooClass f = provider.get(); // This is lazy
于 2010-02-01T11:48:21.533 に答える
15

他の人がすでに答えているように@Inject Injector、Guiceがバインディング自体を定義しているので、単純に使用できます。

通常、アプリに必要なのは1つだけですInjector。静的変数は、シングルトンを挿入するよりも、シングルトンを格納してアクセスするためのさらに簡単な方法です。私たちのWebアプリでは、stripes-guicerInjectorを使用し、必要なときに静的メソッドからを取得しGuiceInjectorFactory.getInjector()ます(たとえば、Hibernateインターセプターで)。

「インジェクターを直接使うべきではない」というアドバイスに少し戸惑っています。またはを呼び出す以外に、他にどのようにインスタンスを注入できますinjector.getInstance()injector.injectMembers()?道はない。はい、プロバイダーメソッドを定義できますが、どこかで何かがインジェクターを使用しない限り、それらが呼び出されることはありません。はい、ServletModuleInjectorのようにを使用するモジュールがあります。自分で作成する必要がありますが、その後はそのままにしておくことができます。InjectorServletModule

したがって、状況によっては、Injector直接使用することを避けることができますが、それはあなたがそれを「使用すべきではない」という意味ではありません。オプションのモジュールを使用せずにGuiceを単独で使用している場合は、Injectorインジェクションをトリガーする他の方法がないため、あらゆる場所で使用する必要があります。(フレームワーク内でコードを1日中記述している開発者は、実際に自分のオブジェクトをインスタンス化する人がいることを忘れることがあると思います。)

于 2011-06-06T17:47:44.933 に答える
8

@gpamparaが言ったProvider<T>ように、レイジー/オプションの初期化に使用する必要があります。また、他の質問への回答で述べたようにInjector、ほとんどの場合、コード内でのへの参照は避ける必要があります。

とは言うものの、Guiceによって作成されたクラスではInjector、オブジェクトを作成しているクラスは、への依存関係を宣言するだけで注入できますInjector。はInjector、バインディングを宣言しなくても、自動的にインジェクションに使用できます。

を注入する場合はInjector、なぜそれを実行するのかを考える必要があります。クラスが依存する実際のインターフェース/クラスへの依存関係を宣言してみませんか?コンストラクターに新しい依存関係を追加するのは、コードの他の場所から依存関係のインスタンスを取得するのと同じくらい簡単でありInjector、コードをはるかに理解しやすくします。

于 2010-02-01T15:06:22.637 に答える