具有多个实现的Guice和接口

new*_*bie 16 java guice

如果我有接口Validator和这个接口的多个实现.如何使用Guice注入任何多个实现?现在我知道我可以使用以下代码注入一个,但它只允许一个实现:

public class MyModule extends AbstractModule {
  @Override 
  protected void configure() {
    bind(Validator.class).to(OneOfMyValidators.class);
  }
}
Run Code Online (Sandbox Code Playgroud)

我想做的是:

Validator v1 = injector.getInstance(Validator1.class);
Validator v2 = injector.getInstance(Validator2.class);
Run Code Online (Sandbox Code Playgroud)

有可能吗?

And*_*mee 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);
Run Code Online (Sandbox Code Playgroud)

在你的构造函数中,你会做:

@Inject
MyClass(@ValidatorOne Validator someValidator,
    @ValidatorTwo Validator otherValidator) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

要直接从a获得带注释的值Injector,您必须使用Guice Key类,如:

Validator v1 = injector.getInstance(Key.get(Validator.class, ValidatorOne.class));
Run Code Online (Sandbox Code Playgroud)

另外,绑定注释对于注入运行时常量非常有用.请参阅以下评论bindConstant:

https://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/Binder.html

  • 让我退一步问:"你希望你的验证依赖类如何要求这些验证器?" 或者,在一个理想的世界中,他们的`@Inject`构造函数会是什么样子?您是否希望代码询问特定实例?(例如`@ValidatorOne Validator someValidator`).或者,类可能想要依赖于`Set <Validator>`?(如果是这样,Multibindings很方便).或者代码可能依赖于一个内部由许多`Validator`s组成的`Validator`?答案肯定会影响最佳解决方案. (3认同)

Har*_* P. 8

与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);
   ...
}
Run Code Online (Sandbox Code Playgroud)

然后从使用的角度来看,例如通过构造函数注入:

class UseCase {
    private Set<Validator> allOfThem;

    @Inject
    public UseCase(Set<Validator> allOfThem) {
        this.allOfThem = allOfThem;
        // e.g. iteratation
        for (Validator oneOfThem : allOfThem) {
            ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


ejb*_*boy 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;
Run Code Online (Sandbox Code Playgroud)