It looks like you're looking for a MapBinder , which is part of Multibindings . Note that you still need to insert some kind of IFactory or another factory interface, because getInstance does not accept the parameter as your getI , and you still need to set the mapping from integers to the class implementation.
MapBinder style
class IModule extends AbstractModule { @Override public void configure() { MapBinder<Integer, I> myBinder = MapBinder.newMapBinder(binder(), Integer.class, I.class); myBinder.addBinding(1).to(A.class);
An injector configured with these modules will provide an injectable Map<Integer, I> , which has an instance of everything connected; here it will be a three-dimensional map from 1 to a fully injected instance of A , from 3 to a C and from 4 to a D This is actually an improvement over your switch example, which used the new keyword and therefore did not introduce any dependencies in A or B
For a better option that does not create so many running instances, enter Map<Integer, Provider<I>> , which MapBinder also provides automatically. Use it like this:
class YourConsumer { @Inject Map<Integer, Provider<I>> iMap; public void yourMethod(int iIndex) {
To provide a default implementation (and an opaque interface), as you did, you will want to implement your own short shell on top of the MapBinder :
class IFactory { @Inject Map<Integer, Provider<I>> iMap; @Inject Provider<B> defaultI; // Bound automatically for every Guice key I getI(int i) { return iMap.containsKey(i) ? iMap.get(i).get() : defaultI.get(); } }
Simplified, factory style
If the above seems redundant, remember that you can enter Injector and create a local Map from the key to the implementation, (You can also use ImmutableMap , as I here).
class IFactory { @Inject Injector injector; // This is a bad idea, except for times like this @Inject Provider<B> defaultI; static final ImmutableMap<Integer, Class<? extends I>> map = ImmutableMap.of( 1, A.class, 3, C.class, 4, D.class); I getI(int i) { return map.containsKey(i) ? injector.getInstance(map.get(i)) : defaultI.get(); } }