I am using MapBinder
to map keys to their respective implementations. Right now I have something like this:
MapBinder<String, Processor> processor
= MapBinder.newMapBinder(binder(), String.class, Processor.class);
processor.addBinding("a1").to(a1Processor.class).in(Scopes.SINGLETON);
processor.addBinding("a2").to(a2Processor.class).in(Scopes.SINGLETON);
processor.addBinding("a3").to(a3Processor.class).in(Scopes.SINGLETON);
It is working the way that it is supposed to. But right now I am thinking of creating a DefaultProcessor
and binding any String
other than a2
and a3
to this DefaultProcessor
. Is it possible to do this?
From the Javadocs of MapBinder
An API to bind multiple map entries separately, only to later inject them as a complete map.
So what you are asking in your question is not possible to achieve via MapBinder.
Although you can write a wrapper around the Map<String, Processor>
and use it.
Suggestion:
@Singleton
class StringProcessorWrapper {
private final Map<String, Processor> processorMap;
private final Processor defaultProcessor;
@Inject
public StringProcessorWrapper(Map<String, Processor> processorMap, @Named("default") Processor defaultProcessor) {
this.processorMap = processorMap;
this.defaultProcessor = defaultProcessor;
}
public Processor get(String key) {
return processorMap.getOrDefault(key, defaultProcessor);
}
}
For this to work you will have to add a binding in your guice module's configure
method like this:
bind(Processor.class).annotatedWith(Names.named("default")).to(DefaultProcessor.class).in(Scopes.SINGLETON);
Now you can inject the StringProcessor
wrapper and use it.
This suggestion is valueable when you need to use the Map
at a lot of places. For a single class, you can just inject the default and use it when key is missing.
If you just want to use the map and avoid adding a separate default binding, you can add a 4th binding in your MapBinder with "default"
key and in the get
method of StringProcessorWrapper
do something like this:
processorMap.getOrDefault(key, processorMap.get("default"));