私はGuiceのAbstractModule
を拡張しており、拡張するクラスの内部でGuiceのインジェクターにアクセスする必要があります。それが可能な場合、可能であれば、どうやって?
これは珍しい要求です。モジュールは、ロジックファイルというよりも構成ファイルに似ています。モジュールは、インジェクターを作成するために読み取られ、インジェクターが作成されるとすぐに、モジュールがその役割を果たします。単純なモジュールの場合、インジェクターは、モジュールを破棄する準備ができるまで文字通り存在しません。
いずれにせよ、クラスXを取得するためにインジェクターを要求するのではなく、通常は_Provider<X>
_を要求する必要があります。 Guiceは X
、_Provider<X>
_、または_Provider<X>
_ のバインディングにX
または_@Provides X
_を挿入します。ほとんどの場合、代わりにこれを行います。そうは言っても、インジェクターをインジェクトすると、インスタンスを反射的に取得したり、インジェクターのバインディング(など)を検査したりできるようになります。
モジュール内からインジェクターにアクセスする必要があるいくつかの有効な理由/設計は次のとおりです。
@Provides
_メソッド内:モジュールには、ミニプロバイダーを _@Provides
_ で注釈されたメソッドに含めることができます。覚えておいてください Injector
is injectable :これらのメソッドのいずれかにインジェクターが必要な場合は、パラメーターとして受け入れることができます。
_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
}
}
_
AbstractModulesは getProvider()
を正確にこの理由で公開しますが、インジェクタが提供する準備ができる前にそのプロバイダでget()
を呼び出すとエラーが発生します(構成時など):
_public class TwoModule extends AbstractModule {
@Override public void configure() {
bind(Thingy.class).toInstance(
new MyThingy(8675309, getProvider(Another.class)));
}
}
_
あなたはおそらくgetProvider(Injector.class)
を呼び出すことができますが、それが機能するかどうかはわかりませんし、なぜあなたがしたいのかわかりません。
これは悪い考えです。 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);
}
}
_