1

すべてのサブクラスに共通のプロバイダーを実装しようとしています。いくつかのスキーマを想像してください: SuperComponent.classComponentA.classandの親ですComponentB.class。私はプロバイダーを持っています:

    @Provides
<T extends SuperComponent> List<T> providesComponents(Provider<T> provider) {
    List<T> componentList = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
        componentList.add(provider.get());
    }
    return componentList;
}

List<ComponentA>アイデアは、オブジェクトおよび/またはList<ComponentB>別のクラスのコンストラクターで必要なときに、このプロバイダーを呼び出すことです。次のようなものを想像してください。

public class ResourceManager {

List<ComponentA> componentAList;
List<ComponentB> componentBList;    

@Inject
public ResourceManager(List<ComponentA> componentAList, List<ComponentB> componentBList) {
    this.componentAList = componentAList;
            this.componentBList = componentBList;
}

次のようなエラーが表示されます。

1) com.google.inject.Provider<T> cannot be used as a key; It is not fully specified.

どうすればそれを機能させることができますか?それぞれに異なるプロバイダーを作成できることはわかっていますがList<ComponentA>List <ComponentB>実際にはコンポーネントの数が2よりもはるかに多いため、必要です...

4

1 に答える 1

0

これを処理するための組み込みの適切な方法はないと思います。Guice は多くのバインディングを実行したり、そのバインディングを検査および操作したりできますが、メタレベルのバインディングを作成するための適切なインターフェースがありません。ただし、いくつかのオプションがあります。

  1. プロバイダーを介して、リストの構築を消費者に任せます。

    public static <T> List<T> createList(Provider<T> provider) {
      List<T> list = new ArrayList<T>();
      for (int i = 0; i < 5; i++) {
        list.add(provider.get());
      }
      return list;
    }
    
    @Inject MyConsumer(Provider<Foo> depProvider) {
      List<Foo> myFoos = createList(depProvider);
    }
    
  2. そのようにバインドする必要があるクラスをリストし、configureメソッドでプロバイダーを作成します。

    public class MyModule extends AbstractModule {
      public void configure() {
        List<Class<?>> classList = Lists.newArrayList(Class1.class, Class2.class);
        for (Class<?> clazz : classList) {
          bind(listOf(clazz)).toProvider(new ComponentListProvider<?>(getProvider(clazz)));
        }
      }
    
      private static <T> Key<List<T>> listOf(Class<T> clazz) {
        return new Key<List<T>>() {};
      }
    
      private static class ComponentListProvider<T> implements Provider<List<T>>() {
        private final Provider<T> wrappedProvider;
    
        ComponentListProvider(Provider<T> wrappedProvider) {
          this.wrappedProvider = wrappedProvider;
        }
    
        @Override public List<T> get() {
          return createList(wrappedProvider);
        }
      }
    }
    

    これは、 が作成されるとすぐに機能getProviderする typed を取得する非常に便利なメソッドです (ただし、作成前ではありません)。ProviderInjector

  3. Guice SPIを使用してモジュール内のすべてのバインディングを反復することにより、上記のいずれかを実行するモジュールを作成します。

それが役立つことを願っています!

于 2013-01-19T01:04:57.570 に答える