I\'m trying to inject things with Google Guice 2.0 and I have the following structure:
FooAction implements Action
BarAction implements Action
What you want for this is Multibindings. Specifically, you want to bind a Set<Action>
(not a List
, but a Set
is probably what you really want anyway) like this:
Multibinder<Action> actionBinder = Multibinder.newSetBinder(binder(), Action.class);
actionBinder.addBinding().to(FooAction.class);
actionBinder.addBinding().to(BarAction.class);
Then you can @Inject
the Set<Action>
anywhere.
Let me show you what I consider an even better way of multibinding things. If you want Action
s to be pluggable and let anyone add them, it's often useful to provide a simple Module
for someone to use that hides needing to instantiate the Multibinder
. Here's an example:
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();
}
}
Now why is this better? It allows someone to use an ActionModule
from anywhere to add more Action
s via the standard binding API. I think it's more readable. Here's an example usage:
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);
}
}
This pattern of using a Module
to hide the multibinder is used in Guice code. It's a little work up front, but keeps things clean. You can also do something similar for a MapBinder
if you need to. Keep in mind you can instantiate as many ActionModule
s as you want.