Sch*_*999 6 java dependency-injection inversion-of-control guice
标准对象工厂可能如下所示:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
是否可以设置绑定以便为我完成切换,即我所做的只是调用getInstance或者注入?我正在寻找辅助注射,但这似乎是不同的主题:https://code.google.com/p/google-guice/wiki/AssistedInject
Jef*_*ica 14
听起来你正在寻找一个MapBinder,它是Multibindings功能的一部分.请注意,您仍然需要放置某种IFactory或其他工厂接口,因为getInstance不像您getI那样使用参数,并且您仍然需要在某处建立从整数到类实现的映射.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
配置有这些模块的注射器将提供Map<Integer, I>具有所有一切实例的注射器; 这里是一个三条目映射,从1到完全注入的A实例,从3到C实例,从4到D实例.这实际上是对你的switch示例的改进,它使用了new关键字,因此没有将任何依赖项注入A或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();
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
但是,要提供"默认"实现(和不透明的接口),您需要在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();
}
}
Run Code Online (Sandbox Code Playgroud)
如果上面看起来有点矫枉过正,请记住,您可以注入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();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6000 次 |
| 最近记录: |