我正在尝试使用Google Guice 2.0注入内容,我有以下结构:
FooAction implements Action
BarAction implements Action
然后我有一个ActionLibrary,其中包含以下构造函数:
ActionLibrary (List<Action> theActions)
当我从Guice请求ActionLibrary的实例时,我希望Guice识别两个已注册的Action类(FooAction,BarAction)并将它们传递给构造函数。这里的动机是当我添加第三个动作BazAction时,它就像在模块中注册它一样简单,它会自动添加到构造函数的列表中。
这可能吗?
答案 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>