如果我有接口Validator和这个接口的多个实现。如何使用Guice注入任何多个实现?现在我知道我可以使用以下代码来注入一个,但它只允许一个实现:
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(Validator.class).to(OneOfMyValidators.class);
}
}
我想做的是:
Validator v1 = injector.getInstance(Validator1.class);
Validator v2 = injector.getInstance(Validator2.class);
有可能吗?
答案 0 :(得分:22)
简答:绑定注释。它们基本上是一种让依赖者提供指向特定实例或实现的提示的方式,而不需要依赖于完整的具体实现类。
请参阅: https://github.com/google/guice/wiki/BindingAnnotations
例如,在模块中,您可以执行以下操作:
bind(Validator.class).annotatedWith(ValidatorOne.class).to(OneOfMyValidators.class);
bind(Validator.class).annotatedWith(ValidatorTwo.class).to(SomeOtherValidator.class);
在你的构造函数中,你会这样做:
@Inject
MyClass(@ValidatorOne Validator someValidator,
@ValidatorTwo Validator otherValidator) {
...
}
要直接从Injector
获取带注释的值,您必须使用Guice Key
类,例如:
Validator v1 = injector.getInstance(Key.get(Validator.class, ValidatorOne.class));
另外,绑定注释对于注入运行时常量非常有用。请参阅以下内容中bindConstant
的评论:
https://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/Binder.html
答案 1 :(得分:7)
在寻找将多个实现动态绑定到接口的解决方案时,我找到了这个线程,类似于Java中的ServiceLoader。答案涵盖了更一般的情况,但它也可用于从集合中获取特定实现。 Multibinder允许将多个实现绑定到一个类型:
public class ValidatorsModule extends AbstractModule {
protected void configure() {
Multibinder<Validator> multibinder
= Multibinder.newSetBinder(binder(), Validator.class);
multibinder.addBinding().toInstance(new ValidatorOne());
multibinder.addBinding().toInstance(new ValidatorTwo());
}
}
//Usage
@Inject Set<Validator> validators;
答案 2 :(得分:5)
与ejboy的提议非常相似,但由于您拥有不同的Validator类,因此您可以绑定到类本身,而不是手动创建实例。
protected void configure() {
...
Multibinder<Validator> mb = Multibinder.newSetBinder(binder(), Validator.class);
mb.addBinding().to(Validator1.class);
mb.addBinding().to(Validator2.class);
mb.addBinding().to(Validator3.class);
...
}
然后从使用角度来看,例如通过构造函数注入:
class UseCase {
private Set<Validator> allOfThem;
@Inject
public UseCase(Set<Validator> allOfThem) {
this.allOfThem = allOfThem;
// e.g. iteratation
for (Validator oneOfThem : allOfThem) {
...
}
}
}
答案 3 :(得分:0)
科特林
这就是我们如何为一个接口的多个实现绑定
a = numgood.nextInt();
使用
Class SomeModule : AbstractModule() {
override fun configure() {
val myBinder: Multibinder<MyInterface> = Multibinder.newSetBinder(binder(), MyInterface::class.java)
myBinder.addBinding().to(Implementation1::class.java)
myBinder.addBinding().to(Implementation2::class.java)
}