[英]Explicitly add binder dependency when binding to Guice provider instance
假設我要創建一個通用提供程序,該提供程序返回集合中的第一項。 就像是:
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;
}
}
現在,我有了各種帶有不同批注的此類集合,並且我想向此提供程序BUT添加綁定,我還希望能夠使用DefaultBindingTargetVisitor和getDependencies()遍歷綁定。
我已經嘗試過類似的東西:
bind(Key.get(type, annotation))
.toProvider(new P(
getProvider(
Key.get(Types.collectionOf(type.getType()), annotation)
)
));
就綁定而言,這很好用,但是遍歷不會啟動,因為Guice沒有檢測到依賴關系。
我無法找出任何其他方法來綁定到帶注釋的生產者,因為它上面沒有注釋。
有什么辦法可以做我想做的事嗎?
謝謝亞倫
這對我有用:
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)]]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.