私は Guice を拡張AbstractModule
しており、拡張クラス内で Guice のインジェクターにアクセスする必要があります。もしそうなら、どのように可能ですか?
2 に答える
これは異常な要求です。モジュールは、ロジック ファイルというよりも構成ファイルに似ています。モジュールはインジェクターを作成するために読み取られ、インジェクターが作成されるとすぐに、モジュールはその仕事を完了します。単純なモジュールの場合、モジュールを破棄する準備が整うまで、インジェクターは文字通り存在しません。
いずれにせよ、クラス X を取得するために Injector を要求するのではなく、通常はProvider<X>
. Guice は、 、、またはのバインディングに対してorを注入するX
Provider<X>
X
Provider<X>
@Provides X
ので、ほとんどの場合、代わりにこれを行うことができます。そうは言っても、インジェクターを注入すると、インスタンスをリフレクティブに取得したり、インジェクターのバインディングを検査したりできます (など)。
モジュール内からインジェクターにアクセスする必要があるいくつかの正当な理由/設計を次に示します。
@Provides
メソッドで:
モジュールには、 で注釈が付けられたメソッド@Provides
にミニプロバイダーを含めることができます。Injector
これは注入可能であることを忘れないでください: これらのメソッドのいずれかで Injector が必要な場合は、それをパラメーターとして受け入れることができます。
public class OneModule extends AbstractModule {
@Override public void configure() { /* ... */ }
@Provides YourDependency getYourDependency(Injector injector) {
return injector.getInstance(Class.forName(yourDependencyName));
}
@Provides Something getSomething(SomethingImpl something) {
return initialize(something); // preferred: only ask for what you need
}
@Provides SomethingElse getSomethingElse(Provider<Thing> thingProvider) {
return new SomethingElse(thingProvider); // asking for a provider works too
}
}
configure() でプロバイダーを取得するには:
AbstractModulesgetProvider()
はまさにこの理由で公開されますがget()
、インジェクターがプロバイダーを提供する準備が整う前 (構成時など) にそのプロバイダーを呼び出すと、エラーが発生します。
public class TwoModule extends AbstractModule {
@Override public void configure() {
bind(Thingy.class).toInstance(
new MyThingy(8675309, getProvider(Another.class)));
}
}
おそらく電話をかけることができますgetProvider(Injector.class)
が、それが機能するかどうかはわかりませんし、なぜ電話したいのかもわかりません.
configure() でインスタンスを取得するには:
これは悪い考えです。すべての構成メソッドが実行されるまで、Guice はインスタンスを提供する準備ができていません。最も近い方法は、他のモジュールを使用して子インジェクターを作成し、それをこのモジュールに渡すことですが、それが必要になることはめったにありません。
public class MainClass {
public static void main(String[] args) {
Injector firstStage =
Guice.createInjector(new OtherModule1(), new OtherModule2());
// An alternative design would @Inject-annotate fields in ThreeModule
// and get it from firstStage, but that's nonstandard and may be confusing.
Injector secondStage =
firstStage.createChildInjector(new ThreeModule(firstStage));
}
}
public class ThreeModule extends AbstractModule {
private final Injector otherInjector;
public ThreeModule(Injector otherInjector) {
this.otherInjector = otherInjector;
}
@Override public void configure() {
bindStuffBasedOn(otherInjector);
}
}
Injector
クラスまたはプロバイダーにを注入できますが、まばらに使用する必要があります。
ここで見つけました:https://groups.google.com/d/msg/google-guice/EiMDuDGei1Q/glxFhHKHHjsJ
参照: https://github.com/google/guice/wiki/InjectingTheInjector
public class MyClass
{
@Inject
public MyClass(Injector injector) { ... }
}
public class MyModule extends AbstractModule {
...
@Provides
public Something provideSomething(Injector injector) { ... }
}