我想提供通用实例,而无需在模块实现中明确声明通用参数。
假设我有一个非常优化的Map实现,并希望每个人都使用它。
class MyVeryOptimizedHashMap<K, V> implements Map<K, V> {}
我知道,使用后不是最好的设计模式,但为了这个例子,这是一个有效的要求:
class SomeInjectee {
@Inject
private Map<String, Integer> myMap;
}
在模块声明工作之后,将此实例绑定到我选择的提供者:
class GenericMapModule extends AbstractModule {
protected void configure() {
bind(new TypeLiteral<Map<String, Integer>>() {}).toProvider(new TypeLiteral<Provider<MyVeryOptimizedHashMap<String, Integer>>>() {});
}
}
问题是我必须明确说明泛型类型参数,我不可能对所有可能的类型做:
class SomeOtherInjectee{
@Inject
private Map<SomeUnknownKey, Long> myMap;
}
这解决了我的问题,但不是很优雅:
class GenericModule extends AbstractModule {
protected void configure() {
bind(new TypeLiteral<Map<?, ?>>() {}).toProvider(new Provider<Map<?,?>>() {
public Map<?, ?> get() {
return new MyVeryOptimizedHashMap();
}
});
}
}
class SomeOtherInjectee {
private Map<SomeUnknownKey, Long> myMap;
@Inject
void setMap(Map<?, ?> mapInstance) {
myMap = (Map<SomeUnknownKey, Long>) mapInstance;
}
}
我正在寻找的是:
class GenericModule extends AbstractModule {
protected void configure() {
bind(TypeLiteral.anyGenericVariant(Map.class)).toProvider(new TypeLiteral<Provider<MyVeryOptimizedHashMap>>(){});
}
}
答案 0 :(得分:0)
如果适用于您的情况,我尝试使用静态实用方法。
class SomeOtherInjectee {
private Map<SomeUnknownKey, Long> myMap = newOptimizedMap();
如果这不适用,那么正如您所见,Guice在泛型方面非常精确,即每个通用变体代表一种独特的绑定。因此anyGenericVariant实际上必须列出所有可能的变体并提前进行绑定。疯狂。
在这种情况下,您可以使用TypeListener注册自定义注入。它看起来像
class SomeOtherInjectee {
@InjectOptimizedMap private Map<SomeUnknownKey, Long> myMap;
或者你做的任何自定义注入注释。
有关如何进行自定义注射的信息,请参阅here for the full example and explanation。