Java 具有多个实现的GUI和接口

Java 具有多个实现的GUI和接口,java,guice,Java,Guice,如果我有接口验证程序和这个接口的多个实现。如何使用Guice注入多个实现中的任何一个?现在我知道我可以使用以下代码注入一个,但它只允许一个实现: public class MyModule extends AbstractModule { @Override protected void configure() { bind(Validator.class).to(OneOfMyValidators.class); } } 我想做的是: Validator v1 = in

如果我有接口验证程序和这个接口的多个实现。如何使用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);

有可能吗?

简短回答:绑定注释。它们基本上是一种让依赖者给出指向特定实例或实现的提示的方法,而不需要依赖于完整的具体实现类

见:

例如,在模块中,您可以执行以下操作:

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) {
  ...
}
要直接从
注入器
获取带注释的值,必须使用Guice
类,如:

Validator v1 = injector.getInstance(Key.get(Validator.class, ValidatorOne.class));
另一方面,绑定注释对于注入运行时常量非常有用。请参阅中的
bindcontent
注释:


我在寻找将多个实现动态绑定到一个接口的解决方案时发现了这个线程,类似于Java中的ServiceLoader。答案涵盖了更一般的情况,但也可用于从集合中获得特定的实现。允许将多个实现绑定到一个类型:

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;
公共类验证器模块扩展了AbstractModule{
受保护的void configure(){
多活页夹多活页夹
=Multibinder.newSetBinder(binder(),Validator.class);
multibinder.addBinding().toInstance(新的ValidatorOne());
multibinder.addBinding().toInstance(新的ValidatorTwo());
}
}
//用法
@注入集验证器;

与ejboy的建议非常相似,但由于您拥有不同的验证器类,因此可以绑定到类本身,而不是手动创建实例

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);
   ...
}
protectedvoid-configure(){
...
Multibinder 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) {
            ...
        }
    }
}
类用例{
私人设置许可证;
@注入
公共用例(设置允许它们){
this.allOfThem=allOfThem;
//例如迭代
用于(其中一个验证器:allOfThem){
...
}
}
}

Kotlin

这就是我们如何为一个接口的多个实现进行绑定的方法

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)
}
Class SomeModule:AbstractModule(){
覆盖乐趣配置(){
val myBinder:Multibinder=Multibinder.newSetBinder(binder(),MyInterface::class.java)
myBinder.addBinding().to(Implementation1::class.java)
myBinder.addBinding().to(Implementation2::class.java)
}
用法

@Inject constructor(private val someVar:Set<@JvmSuppressWildcards MyInterface>)
@injectconstructor(私有val-someVar:Set)

谢谢您的回答,但我不知道这是否适合我的情况,如果有1456个验证器呢?那么我需要1456个注释,每个验证器一个,我已经有了验证器的通用注释。让我退一步问:“您希望依赖于验证的类如何请求这些验证器?”或者,在理想情况下,它们的
@Inject
构造函数是什么样子的?您希望代码请求特定实例吗?(例如
@Validator one Validator someValidator
)。或者,类可能希望依赖于
?(如果是这样的话,多绑定就很方便了)。或者代码应该依赖于单个
验证器
,它内部由许多
验证器
组成?答案肯定会影响最佳解决方案。您可以使用命名键而不是注释@named(“validator1”)您的示例没有注入验证器,只是创建了验证器。您希望如何在实际代码中区分1456实现?是的。我的意思是应用程序可以有x个验证器。可能验证器创建者希望向验证器注入一些依赖项。因此,验证器创建者可以向验证器构造函数添加@injectd获取所需的依赖项。我在com.google.inject命名空间中没有Multibinder。我假设它在不同的版本中…..哪个版本的juice支持此功能?Multibinder是在Guice 2.0中引入的。您使用哪个版本?每个pom文件使用4.1.0:com.google.inject Guice 4.1.0您需要ad中的Guice multibindings模块对guice的补充。请参阅