Search code examples
guice

Initializing mapbinder with a map in guice


I am trying to inject a map as a bean in one of my class (Helper.java). I am planning to create this map in the HelperModule where I have binded Helper.java.

I believe in order to inject a map as a bean, I need to use MapBinder. And then populate all the bindings in the binderOfMap and then ultimately use the map in my class.

public class HelperModule extends AbstractModule {

    @Override
    protected void configure() {
        log.info("Configuring the helper module.");
        configureHelper();

        final MapBinder<String, String> binderOfMap =
                MapBinder.newMapBinder(binder(), new TypeLiteral<String> () {},
                        new TypeLiteral<String>() {},
                        Names.named("CustomMap"));

                Map<String, String> myFieldsMap = 
                           myDependency.getCustomMap(SomeConstants);

        for (Map.Entry<String, String> entry: myFieldsMap.entrySet()) {
          binderOfMap.addBinding(entry.getKey()).toInstance(entry.getValue());
        }

    private void configureHelper() {
        bind(Helper.class).in(Scopes.SINGLETON);
    }
}

Do I have to iterate over the entire myFieldsMap to add to binderOfMap? Or, is there a way to initialize the binderOfMap with the myFieldsMap?

Also, can I now directly inject the Map<String,String> with @Named annotation ("CustomMap") in my class?


Solution

  • According to MapBinder documentation, only addBinding method adds a new entry in the map and takes one key at a time.

    To iterate over myFieldsMap you can use streams, for example

    myFieldsMap.forEach((key, value) -> binderOfMap.addBinding(key).toInstance(value));
    

    Helper constructor can look like this

    @Inject
    public Helper(@Named("CustomMap") Map<String, String> map) {...}
    

    TypeLiteral represents a generic type T, for your case you can simply use

    MapBinder.newMapBinder(binder(), String.class, String.class, Names.named("CustomMap"));