假设我想创建一个返回集合中第一个项目的通用提供程序。类似的东西:
class P extends Provider<T> {
private final Provider<Collection<T>> provider;
FirstItemProvider(Provider<Collection<T>> provider) {
this.provider = provider;
}
@Override
public T get() {
Collection<T> input = provider.get();
Iterator<T> iter = input.iterator();
return iter.hasNext() ? iter.next() : null;
}
}
现在我有各种带有不同注释的集合,我想为这个提供程序添加绑定,但是我也希望能够使用DefaultBindingTargetVisitor和getDependencies()来遍历绑定。
我尝试过类似的事情:
bind(Key.get(type, annotation))
.toProvider(new P(
getProvider(
Key.get(Types.collectionOf(type.getType()), annotation)
)
));
这在绑定方面工作正常,但由于Guice没有检测到依赖性,因此遍历不会被激活。
我无法找出任何其他方式绑定到带注释的生产者,因为它没有注释。
有什么办法可以做我想做的事吗?
由于 亚龙
答案 0 :(得分:2)
这对我有用:
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.inject.Provider;
import com.google.inject.AbstractModule;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderWithDependencies;
class FirstItemProvider<T> implements ProviderWithDependencies<T> {
private final Provider<? extends Collection<? extends T>> collectionProvider;
private final Key<? extends Collection<? extends T>> key;
public FirstItemProvider(Binder binder, Key<? extends Collection<? extends T>> key) {
this.collectionProvider = binder.getProvider(key);
this.key = key;
}
@Override
public T get() {
return collectionProvider.get().iterator().next();
}
@Override
public Set<Dependency<?>> getDependencies() {
return Collections.<Dependency<?>>singleton(Dependency.get(key));
}
}
class FooModule extends AbstractModule {
@Override
protected void configure() {
Key<List<String>> listKey = new Key<List<String>>(Names.named("foo")){};
Key<String> stringKey = new Key<String>(Names.named("foo")){};
bind(listKey).toInstance(Arrays.asList("foo", "bar"));
bind(stringKey).toProvider(new FirstItemProvider<>(binder(), listKey));
}
}
public class Foo {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new FooModule());
Key<String> stringKey = new Key<String>(Names.named("foo")){};
ProviderInstanceBinding<String> binding = (ProviderInstanceBinding<String>)injector.getBinding(stringKey);
System.out.println(binding.getDependencies());
}
}
输出
[Key[type=java.util.List<java.lang.String>, annotation=@com.google.inject.name.Named(value=foo)]]