Search code examples
javadependency-injectionguice

Inject values of a Map with Guice


I have a Guice managed service that injects a couple of other services. The other services are used depending on a key value that is passed to my service method. So I want to make a Map that maps the service to use to the corresponding key:

@Inject
private IServiceA serviceA;

@Inject
private IServiceB serviceB;

private Map<String, IService> mapping;

private Map<String, IService> getMapping() {
    if (mapping == null) {
        mapping = new HashMap<String, IService>();
        mapping.put("keyA", serviceA);
        mapping.put("keyB", serviceB);
    }
}

@Override
public void myServiceMethod(String key) {
    IService serviceToUse = getMapping().get(key);
    // ... use some methods of the identified service
}

This solution works but seem awkward, because I have to have this lazy initialization of the mapping. I tried to use a static block, but the instance members are not yet initialized by Guice at this point.

I would prefer to inject the mapping values directly with Guice, but I don't know how to achieve this.


Solution

  • Just use a MapBinder, e.g.

    protected void configure() {
        MapBinder<String, IService> mapBinder 
            = MapBinder.newMapBinder(binder(), String.class, IService.class);
        mapBinder.addBinding("keyA").to(IServiceA.class);
        mapBinder.addBinding("keyB").to(IserviceB.class);
    }
    

    Then you inject the entire map, e.g.

    public class IServiceController {
       @Inject
       private Map<String, IService> mapping;
    }