A standard object factory may look like this:
interface I { ... }
class A implements I { ... }
class B implements I { ... }
class IFactory {
I getI(int i) {
switch (i) {
case 1: return new A();
default: return new B();
}
}
}
Is it possible to set up bindings so that switch is done for me, i.e. all I do is call getInstance or inject? I was looking at assisted injection but that seems to be different topic: https://code.google.com/p/google-guice/wiki/AssistedInject
It sounds like you're looking for a
MapBinder
, which is part of the Multibindings feature. Note that you'll still need to put in some kind ofIFactory
or other factory interface, becausegetInstance
doesn't take a parameter the way yourgetI
does, and you'll still need to establish a mapping from integer to class implementation somewhere.MapBinder-style
An injector configured with those modules will provide an injectable
Map<Integer, I>
that has an instance of everything bound; here it would be a three-entry map from 1 to a fully-injectedA
instance, from 3 to aC
instance, and from 4 to aD
instance. This is actually an improvement over your switch example, which used thenew
keyword and thus didn't inject any dependencies intoA
orB
.For a better option that doesn't create so many wasted instances, inject a
Map<Integer, Provider<I>>
that MapBinder also provides automatically. Use it like this:To provide a "default" implementation (and opaque interface) the way you did, though, you'll want to implement your own short wrapper on top of the
MapBinder
map:Simpler, factory-style
If the above looks like overkill, remember that you can inject an
Injector
and create a localMap
from key to implementation. (You can also useImmutableMap
like I did here).