【问题标题】:Is binding to a TypeLiteral a good or bad practice in google guice绑定到 TypeLiteral 在 google guice 中是好是坏
【发布时间】:2012-04-26 10:28:13
【问题描述】:

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 的意见。恐怕我的选址有点短,因此看不到这种方法的缺陷。

【问题讨论】:

  • 我不太明白泛型类如何“在适当键入时”提供非泛型接口的实现。是否编译?你能举个例子吗?
  • 也许我把这个例子简单化了。我会更新的。
  • @axtavt 我希望这个问题现在更清楚了。
  • 我有点困惑。对于第二个和第三个示例,您的意思是使用bind(new TypeLiteral&lt;MyGenericInterface&lt;T&gt;&gt;(){})... 而不是bind(MyGenericInterface&lt;T&gt;.class)...?正如您在问题顶部所说的那样,C&lt;T&gt;.class 是没有意义的。那么,您的问题只是“我应该绑定到泛型类吗?我应该绑定到非泛型类型类吗?”
  • @AndrewMcNamee 你是对的,我犯了一个错误。我的问题是您已经猜到“我应该绑定到泛型类吗?我应该绑定到非泛型类型类吗?

标签: java dependency-injection guice


【解决方案1】:

在这种情况下,使用TypeLiteral 进行通用实现让我觉得要好得多。

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

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

总而言之,使用TypeLiteral 通常没有任何问题。如果它在绑定子句的.to(...) 部分(与bind(...) 相反,它甚至不会影响Module 绑定的公开可见部分,所以我认为没有什么可做的担心。

【讨论】:

    【解决方案2】:

    通常有两种情况:

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

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

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

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

    bind(new TypeLiteral&lt;MyGenericInterface&lt;T&gt;&gt;() {}).to(new TypeLiteral&lt;MyGenericClass&lt;T&gt;&gt;() {});

    MyTypedClass extends MyGenericClass&lt;T&gt;

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

    【讨论】:

    • 问题更多是关于良好实践。您的示例处理 bind() 参数是通用的情况。我的问题更多的是关于 to() 参数是通用的情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多