基本的に私の質問は、このテストに合格する方法に要約されます。
private static class DefaultModule extends AbstractModule {
@Override protected void configure() {
}
}
private static class ParentModule extends DefaultModule{}
private static class ChildModule extends DefaultModule {}
private static class DependsOnInjector{
@Inject
public Injector depdendency;
}
@Test
public void when_instancing_a_class_that_depends_on_an_injector_it_should_yield_the_most_childish(){
//childish :p
Injector parent = Guice.createInjector(new ParentModule());
Injector child = parent.createChildInjector(new ChildModule());
DependsOnInjector objectWithInjector = child.getInstance(DependsOnInjector.class);
assertThat(objectWithInjector.depdendency).isSameAs(child);
}
しかし、おそらく私は要点を見逃しています:スタックオーバーフローは、私がしていることをするのは罪であるとあなたに信じさせるでしょう(インジェクターへの参照を持つファクトリを紹介します。 product)、そして私がやっているのは service-locator に迫っていることです。これは悪い動きです。しかし、これを回避する方法がわかりません。
7 つの実装者を持つ「視覚化」というインターフェイスがあります。実行すると、データセットに応じて、作成およびレンダリングするこれらのビジュアライザーのセットが選択されます。Injector フィールドを持つファクトリでは、メソッドを追加するだけです
public <TVis extends Visualization> TVis makeVisualization(Class<TVis> desiredVisualizationType){
return injector.getInstance(desiredVisualizationType);
}
ファクトリに IOC コンテナをフィールドとして保持させる唯一の方法は、7 つの Guice の支援注入ファクトリ (実装ごとに 1 つ) をスイッチで選択することです。それはかなり厄介です。
これはいくつかの例の 1 つです。最もローカルなインジェクターを取得するための良い方法が本当に欲しいです。
編集して明確にする:
インジェクターをある種のデコーダーにラップすると便利な場所がいくつかあります。ビジュアライザーは 1 つのインスタンスでしたが、他にもいくつかあります。Map バインディングに関するヒントをありがとう。私が今抱えている問題は、ビジュアライザー (良くも悪くも...もっと悪いと思います) が必要になるたびにインスタンス化されることを期待していることです。したがって、マップ バインディングを使用しても、ビジュアライザーのデコード ロジック クラスにインジェクターを挿入する必要があるのではないでしょうか?
私が持っているモジュールの数について: 私は現在 4 つの guice モジュールを持っています: 私の大きな (本当に) シングルトン サービスの多くが登録されている共有モジュール、次に「ホスティング」UI 用、そして「問題セットアップ」UI 用の 1 つです。 、もう 1 つは「外部ツール」UI 用です (実際には、テスト環境用にもう 1 つあります)。後者の 2 つの UI モジュールは任意の数だけぶらぶらしていて、それぞれに非常に遅く作成されたオブジェクトがいくつかあります。つまり、子モジュールを使用しないと、いくつかのマップ バインダーが残され、それぞれに実行時にバインディングが追加されると思います (そして、おそらくメモリ リークのために、破棄時に何らかの削除ロジックが行われます)。私の(構成された!)guiceモジュールツリー(継承ツリーではありません!)を持っている方がずっときれいに思えます。
助けてくれてありがとう、そして既存の提案に感謝します。