簡體   English   中英

綁定到Guice提供者實例時顯式添加綁定器依賴項

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM