Guiceには、クラス「Panel」とクラス「Controller」があります。両者は相互に関連しています。コントローラには3つのサブクラス(たとえば、A、B、C)があります。プログラマーに、ニーズに応じて、3つのコントローラーのいずれかを注入したPanelのインスタンスを取得する簡単な方法を提供したいと思います。
たとえば、コードの特定のポイントで、プログラマーはControllerAが挿入されたPanelのインスタンスを取得したい場合がありますが、別の場所ではControllerBが含まれたPanelが必要になる場合があります。
どうすればそれを達成できますか?
2 に答える
バインディング アノテーションを使用して、ユーザーが必要なものを指定できるようにすることができます: http://code.google.com/p/google-guice/wiki/BindingAnnotations
次のように注釈を作成します。
import com.google.inject.BindingAnnotation;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
public @interface WithClassA{}
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
public @interface WithClassB{}
...
次に、ユーザーのコンストラクターは次のようになります
@Inject
public MyConstructor(@WithClassA Panel thePanel) {...}
次に、バインディングを行うときに、.annotatedWith を使用します。
bind(Panel.class)
.annotatedWith(WithClassA.class)
.toProvider(ProviderThatReturnsPanelConstructedWithA.class);
bind(Panel.class)
.annotatedWith(WithClassB.class)
.toProvider(ProviderThatReturnsPanelConstructedWithB.class);
念のため、プロバイダーの設定方法に関するドキュメントを次に示します: http://code.google.com/p/google-guice/wiki/ProviderBindings
私は考えられる解決策を思いつきました: Guice を使用すると、クラスだけでなく、プロバイダー インスタンスにバインドできます。したがって、引数が 1 つのコンストラクターを持つプロバイダーを 1 つだけ作成し、次のようにバインドできます。
bind(Panel.class).annotatedWith(WithClassA.class).toProvider(new MyProvider("a"))
コンストラクターの引数の型は、同じ WithClassA.class を渡して、列挙型や注釈などの他の型にすることができます。
これはプロバイダーを節約する良い方法です。欠点は、プロバイダーに依存性注入がないことですが、このシナリオでは、これはなくても問題ありません。