web-dev-qa-db-ja.com

クラスのコレクションにGuiceを注入する

私はGoogleGuice 2.0で物を注入しようとしていますが、次の構造になっています。

FooAction implements Action
BarAction implements Action

次に、次のコンストラクターを持つActionLibraryがあります。

ActionLibrary (List<Action> theActions)

GuiceにActionLibraryのインスタンスをリクエストするとき、Guiceに登録済みの両方のActionクラス(FooAction、BarAction)を識別させ、それらをコンストラクターに渡します。ここでの動機は、3番目のアクションBazActionを追加すると、それをモジュールに登録するのと同じくらい簡単で、コンストラクターのリストに自動的に追加されるということです。

これは可能ですか?

32
Scruffers

これに必要なのは Multibindings です。具体的には、次のようにSet<Action>Listではありませんが、Setはおそらく本当に必要なものです)をバインドする必要があります。

Multibinder<Action> actionBinder = Multibinder.newSetBinder(binder(), Action.class);
actionBinder.addBinding().to(FooAction.class);
actionBinder.addBinding().to(BarAction.class);

次に、どこでも@InjectSet<Action>できます。

40
ColinD

マルチバインディングのさらに良い方法と私が考えるものをお見せしましょう。 Actionsをプラグイン可能にして、誰でも追加できるようにしたい場合は、Moduleをインスタンス化する必要を隠すために誰かが使用できる単純なMultibinderを提供すると便利なことがよくあります。次に例を示します。

public abstract class ActionModule extends AbstractModule {
  private Multibinder<Action> actionBinder;

  @Override protected void configure() {
    actionBinder = Multibinder.newSetBinder(binder(), Action.class);
    configureActions();
  }

  /**
   * Override this method to call {@link #bindAction}.
   */
  protected abstract void configureActions();

  protected final LinkedBindingBuilder<Action> bindAction() {
    return actionBinder.addBinding();
  }
}

なぜこれが良いのですか?これにより、誰かがどこからでもActionModuleを使用して、標準のバインディングAPIを介してActionsを追加できます。読みやすいと思います。使用例は次のとおりです。

public final class MyStandardActionModule extends ActionModule() {
  @Override protected void configureActions() {
    bindAction().to(FooAction.class);
    bindAction().to(BarAction.class);
    // If you need to instantiate an action through a Provider, do this.
    bindAction().toProvider(BazActionProvider.class);
    // You can also scope stuff:
    bindAction().to(MySingletonAction.class).in(Singleton.class);
  }
}

Moduleを使用してマルチバインダーを非表示にするこのパターンは、Guiceコードで使用されます。少し前もって作業しますが、物事をきれいに保ちます。必要に応じて、MapBinderに対して同様のことを行うこともできます。必要な数のActionModuleをインスタンス化できることに注意してください。

21
Tom