我有一个接口Producer<T>
和一个实现FooProducer
的具体Producer<Foo>
。将它绑在guice中看起来很丑陋:
bind(new TypeLiteral<Producer<Foo>>() {}).to(FooProducer.class);
我有很多这样的绑定。我尝试过以下方法:
static <T> TypeLiteral<Producer<T>> producer() {
return new TypeLiteral<Producer<T>>(){};
}
以这种方式拨打电话:
bind(ContainingClass.<Foo>producer()).to(FooProducer.class);
但它在Producer<T> is not specific enough...
。
我是以错误的方式解决这个问题吗?
答案 0 :(得分:8)
而不是
bind(new TypeLiteral<Producer<Foo>>() {}).to(FooProducer.class);
尝试像
这样的便利方法static <T> Key<Producer<T>> producerOf(Class<T> type) {
return (Key<Producer<T>>)Key.get(Types.newParameterizedType(Producer.class,type));
}
然后在你的模块中
bind(producerOf(Foo.class)).to(FooProducer.class);
未经检查的演员应该是安全的。密钥是com.google.inject.Key,而类型是com.google.inject.util.Types。
祝你好运答案 1 :(得分:7)
您可以输入new Key<Producer<Foo>>(){}
而不是new TypeLiteral<Producer<Foo>>(){}
来保存8个字符。或者使用等效的@Provides方法:
@Provides
public Producer<Foo> provideFooProducer(FooProducer fooProducer) {
return fooProducer;
}
答案 2 :(得分:3)
我认为由于TypeLiteral
的工作方式,您必须实际编写new TypeLiteral<Producer<Foo>>(){}
,否则将无法获得必要的类型信息。它们利用了这样一个事实,即完全指定其泛型类型的类可以获得有关所检索类型的信息。当您编写new TypeLiteral<Producer<T>>(){}
时,您没有指定T
是什么,因此该信息不可用。
这是主观的,但我不认为创建类型字面看起来太丑陋,考虑它的作用。
顺便说一句,我不知道你的Producer
接口是做什么的,但如果它只是用于生成T
的实例(使用的方法没有参数),你可以改用Guice的Provider
界面。然后你就必须这样做:
bind(Foo.class).toProvider(FooProvider.class);
您可以在任何地方注入Foo
或Provider<Foo>
。