Atom Feed SITE FEED   ADD TO GOOGLE READER

Guice Multibinder API proposal

Multibindings is an idea to allow multiple independent modules to contribute elements to a collection. There's lots of proposed APIs to add multibindings to Guice.

Unlike almost all of the existing proposals, this strategy can be used to add multibindings as an extension to Guice. Therefore we don't increase the complexity of the existing Binder API in the much more common non-multibinding case. The API:
public class Multibinder<T> {

/**
* Returns a new multibinder that collects instances of {@code type} in a list.
*/
static <T> Multibinder<T> newListBinder(Binder binder, Class<T> type);

/**
* Returns a new multibinder that collects instances of {@code type} in a set.
*/
static <T> Multibinder<T> newSetBinder(Binder binder, Class<T> type);

/**
* Build a new element in the bound collection.
*/
AnnotatedBindingBuilder<T> addBinding();
}

... and here's what the client code would look like:
  public static void testMultibinder() {
AbstractModule stanCartmanKennyModule = new AbstractModule() {
protected void configure() {
Multibinder<String> stringBinder
= Multibinder.newSetBinder(binder(), String.class);

stringBinder.addBinding().toInstance("Stan");
stringBinder.addBinding().annotatedWith(Names.named("Fatass")).toInstance("Cartman");
stringBinder.addBinding().toProvider(new Provider<String>() {
public String get() {
return "Kenny";
}
});
}
};

AbstractModule kyleModule = new AbstractModule() {
protected void configure() {
Multibinder.newSetBinder(binder(), String.class)
.addBinding().toInstance("Kyle");
}
};

Injector injector = Guice.createInjector(stanCartmanKennyModule, kyleModule);

Set<String> boys = injector.getInstance(Key.get(new TypeLiteral<Set<String>>() {}));
assertEquals(Sets.newHashSet("Stan", "Cartman", "Kenny", "Kyle"), boys);
assertEquals("Cartman", Key.get(String.class, Names.named("Fatass"));
}

Note that I've simplified the code above by omitting some details (annotating the collections, binding collections of parameterized types).

I think this API is both compact and convenient. What's your favourite multibinding API?
I think this is one of the best proposals. Maybe add delegating methods to AbsractModule, like 'listBinder()'. I'd also try to get rid of addBinding(). Those two things will make your code look as if it was there since 1.0.
FYI - this proposal has been implemented.