Using Multibinder and MapBinder at the same time.

425 views
Skip to first unread message

Kazu TOMITA

unread,
Aug 3, 2011, 11:37:53 AM8/3/11
to google-guice
Hello.

When I used Multibinder and MapBinder at the same time, I encountered
a strange result.
I wrote the following code in order to add a FlickrPhotoSummarizer
object into Set and Map.

protected void configure() {
Multibinder<UriSummarizer> uriBinder =
Multibinder.newSetBinder(binder(), UriSummarizer.class);
uriBinder.addBinding().to(FlickrPhotoSummarizer.class);


MapBinder<String, UriSummarizer> uriMapBinder =
MapBinder.newMapBinder(binder(), String.class,
UriSummarizer.class);

uriMapBinder.addBinding("flickr").to(FlickrPhotoSummarizer.class); //
A
}

So, Set<UriSummarizer> was injected to the following class.

public class ClientWithMultibinder implements Client {
private Set<UriSummarizer> summarizers;

@Inject
public ClientWithMultibinder(Set<UriSummarizer> summarizers) {
this.summarizers = summarizers;
}

........
}

I expected that summarizers shoud have only one FlickrPhotoSummarizer
object. But it had two.
I commented out "A" line on trial, and it had one.

I can't understand what happened.
I hope sombody helps me.

Thank you for your reading my awkward English.

limpb...@gmail.com

unread,
Aug 9, 2011, 1:38:55 AM8/9/11
to google-guice
Looks like you've found a bug! Behind the scenes Guice is using a set
binder for the map's elements; unfortunately it isn't guarding this
from collision with similar sets.

I'll look into getting this fixed for our next release. In the
interim, you can workaround by using an annotation on your map binder.
Then bind the key you want (the unannotated map) to the key that you
have:

Injector injector = Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
Multibinder.newSetBinder(binder(), String.class)
.addBinding().toInstance("A");

Named uniqueName = Names.named(UUID.randomUUID().toString());
MapBinder.newMapBinder(binder(), String.class, String.class,
uniqueName)
.addBinding("B").toInstance("b");
bind(new Key<Map<String, String>>() {}).to(new Key<Map<String,
String>>(uniqueName) {});
}
});

Cheers,
Jesse
Reply all
Reply to author
Forward
0 new messages