用Guice注入类的集合

Scr*_*ers 32 java guice

我正在尝试用Google Guice 2.0注入东西,我有以下结构:

FooAction implements Action
BarAction implements Action
Run Code Online (Sandbox Code Playgroud)

然后我有一个ActionLibrary与以下构造函数:

ActionLibrary (List<Action> theActions)
Run Code Online (Sandbox Code Playgroud)

当我从Guice请求一个ActionLibrary实例时,我希望Guice能够识别两个已注册的Action类(FooAction,BarAction)并将它们传递给构造函数.这里的动机是当我添加第三个动作BazAction时,它就像在模块中注册它一样简单,它会自动添加到构造函数的列表中.

这可能吗?

Col*_*inD 41

你想要的是Multibindings.具体来说,你想要绑定一个Set<Action>(不是a List,但Set很可能是你真正想要的东西),如下所示:

Multibinder<Action> actionBinder = Multibinder.newSetBinder(binder(), Action.class);
actionBinder.addBinding().to(FooAction.class);
actionBinder.addBinding().to(BarAction.class);
Run Code Online (Sandbox Code Playgroud)

然后你可以@InjectSet<Action>任何地方.

  • `List`没有意义,因为`Multibinder`的整个想法是它收集来自多个模块的绑定......并且没有可靠的用户定义的项目顺序.如果你真的需要一个具有特定顺序的项目的`List`,那么自己创建该列表并直接绑定它真的很有意义.但是"Multibinder"的典型用例是绑定接口的多个实现,在这种情况下,顺序通常应该无关紧要,并且您不需要多个相同的东西. (2认同)

Tom*_*Tom 21

让我告诉你我认为更好的多重绑定方式.如果你想要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();
  }
}
Run Code Online (Sandbox Code Playgroud)

现在为什么这样更好?它允许某人使用ActionModule任何地方Action通过标准绑定API 添加更多s.我认为它更具可读性.这是一个示例用法:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

Module在Guice代码中使用这种使用隐藏多重绑定器的模式.这是一个小工作,但保持清洁.MapBinder如果需要,您也可以为a做类似的事情.请记住,您可以根据需要实例化多个ActionModules.