听起来您正在寻找
MapBinder,这是多重绑定功能的一部分。请注意,您仍然需要放入某种
IFactory工厂接口或其他工厂接口,因为
getInstance它所采用的参数
getI并不像您所使用的那样,并且您仍然需要在
某个地方 建立从整数到类实现的映射。
MapBinder样式
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); // Add more here. }}// You can even split the MapBinding across Modules, if you'd like.class SomeOtherModule extends AbstractModule { @Override public void configure() { // MapBinder.newMapBinder does not complain about duplicate bindings // as long as the keys are different. MapBinder<Integer, I> myBinder = MapBinder.newMapBinder(binder(), Integer.class, I.class); myBinder.addBinding(3).to(C.class); myBinder.addBinding(4).to(D.class); }}配置有这些模块的注入器将提供
Map<Integer,I>具有所有绑定实例的注入器。这里是从1到完全注入
A实例,从3到
C实例以及从4到
D实例的三项映射。实际上,这是对您的switch示例的改进,该示例使用了
new关键字,因此没有向
Aor
注入任何依赖项
B。
对于不会创建太多浪费实例的更好选择,请注入
Map<Integer, Provider<I>>MapBinder也自动提供的。像这样使用它:
class YourConsumer { @Inject Map<Integer, Provider<I>> iMap; public void yourMethod(int iIndex) { // get an I implementor I i = iMap.get(iIndex).get(); // ... }}但是,要提供一种“默认”实现(和不透明的接口),您需要在
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(); }}更简单的工厂风格
如果以上内容看起来有些矫kill过正,请记住您可以注入
Injector并创建一个
Map从密钥到实现的本地方法。(您也可以
ImmutableMap像在这里一样使用)。
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(); }}


