8

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,后一种方法会导致代码过于冗长。因此我倾向于使用前者。

我很想听听其他人对在 guice 绑定的 to 子句中使用 TypeLiteral 的意见。恐怕我的选址可能有点短,因此看不到这种方法的缺陷。

4

2 回答 2

2

在这种情况下,将 aTypeLiteral用于通用实现让我觉得要好得多。

让我这样说:“MyTypedClass如果你不使用 Guice,子类会存在吗?”。Guice 的一个基本准则是:你不应该改变你的实现类来适应 DI 框架(嗯,除了@Inject注释之类的东西)。

你从具体但通用的类中获得什么?一大损失是您必须在所有子类中复制 MyGenericClass 的构造函数。总而言之,这似乎是额外的代码,没有太多收获。

总而言之,使用TypeLiteral. 如果它在.to(...)绑定条款的部分(与 相对bind(...),它甚至不会影响您Module的绑定的公开可见部分,所以我认为没有什么可担心的。

于 2012-06-09T00:01:17.483 回答
1

通常有两种情况:

  1. 你想绑定到的所有MyGenericInterface实现MyGenericClass
  2. 您想MyGenericInterface根据其类型绑定 base 的实现

对于第一个场景,bind(MyGenericInterface).to(MyGenericClass);就足够了,更简单,更容易理解。

对于第二种情况,您需要将特定类的实现绑定到特定实现,TypeLiteral 将发挥作用。

此外,您问题中的代码不清楚T是实际类还是泛型类型。如果是泛型类型,

bind(new TypeLiteral<MyGenericInterface<T>>() {}).to(new TypeLiteral<MyGenericClass<T>>() {});

MyTypedClass extends MyGenericClass<T>

不会编译,因为没有提供一些实际的类。

于 2012-06-01T07:22:46.600 回答