8

Google のガイダンスは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

この場合、TypeLiteral一般的な実装に a を使用すると、はるかに優れていると思います。

MyTypedClass「Guice を使用していなかったら、サブクラスは存在していたでしょうか?」という言い方をしましょう。Guice の重要なガイドラインは次のとおりです。DI フレームワークに合わせて実装クラスを変更する必要はありません (ただし、@Injectアノテーションなどは例外です)。

具体的でありながら一般的なクラスをサブクラス化することで、何が得られるのでしょうか? 大きな損失の 1 つは、すべてのサブクラスで MyGenericClass のコンストラクターを複製する必要があることです。全体として、あまり利益のない余分なコードのように見えます。

全体として、一般的に . を使用しても問題はありませんTypeLiteral。そして、それ.to(...)が束縛句の部分にある場合 ( とは対照的にbind(...)、あなたの束縛の公に見える部分には影響しModuleませんので、あまり心配する必要はないと思います.

于 2012-06-09T00:01:17.483 に答える
1

通常、2つのシナリオがあります。

  1. のすべての実装をにバインドMyGenericInterfaceするMyGenericClass
  2. MyGenericInterfaceそのタイプに基づいて実装をバインドしたい

最初のシナリオでbind(MyGenericInterface).to(MyGenericClass);は、十分で、シンプルで、理解しやすいでしょう。

2番目のシナリオでは、特定のクラスの実装を特定の実装にバインドする必要があります。これにより、TypeLiteralが機能します。

さらに、質問のコードTは、実際のクラスなのかジェネリック型なのかが明確ではありません。ジェネリック型の場合、

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

MyTypedClass extends MyGenericClass<T>

一部の実際のクラスが提供されていないため、コンパイルされません。

于 2012-06-01T07:22:46.600 に答える