Google guice使用new TypeLiteral<C<T>>() {}
来克服我们不能使用C<T>.class
的事实。
现在,以下情况是常见的:
bind(new TypeLiteral<C<T>>() {}).to(MyCSubclassTypedToT.class);
然而,想象一下不同的场景。我们有一个泛型接口,我们想要注入它,我们的实现是由一个泛型类提供的。
Guice允许您这样做:
bind(new TypeLiteral<MyGenericInterface<T>>() {}).to(new TypeLiteral<MyGenericClass<T>>() {});
另一种方法是像这样扩展MyGenericClass:
MyTypedClass extends MyGenericClass<T>
然后像这样绑定它:
bind(MyGenericInterface<T>>() {}).to(MyTypedClass.class);
如果MyGenericInterface被大量注入(尽管类型不同),并且每次我注入它时都使用MyGenericClass,则后一种方法会导致代码过于冗长。因此,我倾向于使用前者。
我非常希望听到其他人对TypeLiteral在guice绑定的to子句中的使用的意见。我担心我可能会有点短视,因此看不到这种方法的陷阱。
发布于 2012-06-09 00:01:17
在这种情况下,在我看来,使用TypeLiteral
实现泛型要好得多。
让我这样表述:“如果您不使用Guice,子类MyTypedClass
还会存在吗?”Guice的一个基本原则是:你不应该改变你的实现类来适应DI框架(好的,除了像@Inject
注解这样的东西)。
你从继承这个具体而又泛型的类中得到了什么?一个很大的损失是你必须在所有的子类中复制MyGenericClass的构造函数。总而言之,它看起来像是额外的代码,没有太多的收获。
总而言之,使用TypeLiteral
通常没什么问题。如果它在binding子句的.to(...)
部分(与bind(...)
相反,它甚至不会影响Module
绑定的公开可见部分,所以我认为没有太多需要担心的)。
发布于 2012-06-01 07:22:47
通常有两种情况:
MyGenericInterface
的所有实现绑定到MyGenericClass
绑定MyGenericInterface
的实现
对于第一种情况,bind(MyGenericInterface).to(MyGenericClass);
就足够了,更简单,也更容易理解。
对于第二个场景,您将需要将特定类的实现绑定到特定的实现,这将由TypeLiteral发挥作用。
此外,您问题中的代码不清楚T
是实际的类还是泛型类型。如果它是泛型类型,
bind(new TypeLiteral<MyGenericInterface<T>>() {}).to(new TypeLiteral<MyGenericClass<T>>() {});
和
MyTypedClass extends MyGenericClass<T>
不会编译,因为没有提供一些实际的类。
https://stackoverflow.com/questions/10331610
复制相似问题