我正在尝试为所有子类实现一个公共提供程序,想象一些模式:
SuperComponent.class
是ComponentA.class
和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 ...
答案 0 :(得分:0)
我不认为有一个很好的内置方法来处理这个问题 - Guice可以绑定很多,或检查和操作它的绑定,但没有良好的接口来创建元级绑定。不过你确实有几个选择:
通过提供商将列表构建留给消费者:
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);
}
列出您需要绑定的类,并使用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
,这是一种非常方便的方法,可以检索键入的Provider
,该Injector
会在创建{{1}}之后立即生效(但不会在之前)。
使用Guice SPI通过迭代模块中的每个绑定来编写执行上述任一操作的模块。
希望有所帮助!