如何通过Guice在嵌套模块方案中注入具有相同接口的不同实现的列表?

时间:2018-10-24 01:43:58

标签: dependency-injection guice guice-3

有一个接口DCE,它由类DCEImpl实现,该类具有依赖项,例如字符串S,它通过其构造函数获取。

S的范围有限,例如S只能取值{'A','B','C'}。

已有一个Guice模块,该模块在其构造函数中接受S的值,然后将接口DCE绑定到正确初始化的DCEImpl版本。

public class DCEModule extends AbstractModule {
    private final String s;
    public DCEModule(String s){
       this.s = s;
    }
    protected void configure() {
      bind(DCE.class).toInstance(new DCEImpl(s));
    }
}

现在我有一个类C,它需要一个List<DCE>的所有3种实现方式(实际上比3种实现要多得多,以3种为例)。

我想通过C中的Guice插入此列表。为此,我创建了一个新模块DCEPModule,它将以这种方式提供一个List<DCE>

@Provides
List<DCE> getDCE() {
      for(String s: S){
            Module m = new DCEModule(s);
            install(m);
            Injector injector = Guice.createInjector(m);
            listDomains.add(injector.getInstance(DCE.class));
        }
}

我的问题是我不想在此模块中调用新的注射器,因为DCEPModule将由其他模块安装。

public class NewModule extends AbstractModule {
   protected void configure() {
      install(DCEPModule);
    }

}

我想要一种方法来获取List<DCE>,而无需在DCEPModule中显式创建新的注入器。

1 个答案:

答案 0 :(得分:0)

您可以使用Multibinderjavadocwiki)来实现。 这是一个示例:

public class SnacksModule extends AbstractModule {
    protected void configure(){
         Multibinder<Snack> multibinder = Multibinder.newSetBinder(binder(), Snack.class);
         multibinder.addBinding().toInstance(new Twix());
         multibinder.addBinding().toProvider(SnickersProvider.class);
         multibinder.addBinding().to(Skittles.class);
    }
}

现在,多活页夹将提供一个Set<Snack>。如果您绝对需要List而不是Set,则可以向模块添加如下方法:

@Provides
public List<Snack> getSnackList(Set<Snack> snackSet) {
    return new ArrayList(snackSet);
}

您可以在多个模块中将实现添加到同一Multibinding中。调用Multibinder.newSetBinder(binder, type)时,不一定会创建新的多重绑定。如果该类型的多重绑定已经存在,那么您将获得现有的多重绑定。