用Guice注入类的集合

时间:2010-12-10 16:01:13

标签: java guice

我正在尝试使用Google Guice 2.0注入内容,我有以下结构:

FooAction implements Action
BarAction implements Action

然后我有一个ActionLibrary,其中包含以下构造函数:

ActionLibrary (List<Action> theActions)

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

这可能吗?

2 个答案:

答案 0 :(得分:39)

你想要的是Multibindings。具体来说,您希望绑定Set<Action>(不是List,但Set可能是您真正想要的东西),如下所示:

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

然后您可以@Inject Set<Action>任意位置。

答案 1 :(得分:21)

让我告诉你我认为更好的多重绑定方式。如果您希望Action是可插入的并且允许任何人添加它们,那么为某人使用需要实例化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添加更多Action。我认为它更具可读性。以下是一个示例用法:

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个。{/ p>