2

モジュール実装内でジェネリック パラメータを明示的に指定せずに、ジェネリック インスタンスを提供したい。

非常に最適化された Map 実装があり、誰もがそれを使用できるようにしたいとしましょう。

class MyVeryOptimizedHashMap<K, V> implements Map<K, V> {}

次の使用法は最適な設計パターンではないことはわかっていますが、例のために、これは有効な要件です。

class SomeInjectee {
  @Inject
  private Map<String, Integer> myMap;
}

このインスタンスを選択したプロバイダにバインドするには、次のモジュール宣言が機能します。

class GenericMapModule extends AbstractModule {
  protected void configure() {
    bind(new TypeLiteral<Map<String, Integer>>() {}).toProvider(new TypeLiteral<Provider<MyVeryOptimizedHashMap<String, Integer>>>() {});
  }
}

問題は、ジェネリック型パラメーターを明示的に指定する必要があることです。これは、考えられるすべての型に対して行うことはできません。

class SomeOtherInjectee{
  @Inject
  private Map<SomeUnknownKey, Long> myMap;
}

これは私の問題を解決しますが、あまりエレガントではありません:

class GenericModule extends AbstractModule {
  protected void configure() {
    bind(new TypeLiteral<Map<?, ?>>() {}).toProvider(new Provider<Map<?,?>>() {
      public Map<?, ?> get() {
        return new MyVeryOptimizedHashMap();
      }
    });
  }
}

class SomeOtherInjectee {
  private Map<SomeUnknownKey, Long> myMap;

  @Inject
  void setMap(Map<?, ?> mapInstance) {
    myMap = (Map<SomeUnknownKey, Long>) mapInstance;
  }
}

私が探しているのはそのようなものです:

class GenericModule extends AbstractModule {
  protected void configure() {
    bind(TypeLiteral.anyGenericVariant(Map.class)).toProvider(new TypeLiteral<Provider<MyVeryOptimizedHashMap>>(){});        
  }
}
4

1 に答える 1

0

あなたの場合に該当する場合は、静的ユーティリティ メソッドを試してみます。

class SomeOtherInjectee {
    private Map<SomeUnknownKey, Long> myMap = newOptimizedMap();

これが当てはまらない場合、ご覧のとおり、Guice はジェネリックに関して非常に正確です。つまり、各ジェネリック バリアントは一意のバインドを表します。そのため、anyGenericVariant は実際には、考えられるすべてのバリアントをリストし、事前にバインドを作成する必要がありました。クレイジー。

そのような場合にできることは、TypeListener を使用してカスタム インジェクションを登録することです。次のようになります

class SomeOtherInjectee {
    @InjectOptimizedMap private Map<SomeUnknownKey, Long> myMap;

または、作成するカスタム注入注釈は何でも。

カスタム インジェクションの実行方法に関する完全な例と説明については、こちらを参照してください。

于 2013-04-18T07:51:28.187 に答える