1

有一个接口 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 个)。

我想通过 Guice 将这个列表注入到C. 为此,我创建了一个新模块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.

4

1 回答 1

1

您可以通过使用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);
    }
}

现在,multibinder 将提供一个Set<Snack>. 如果您绝对需要 aList而不是 a Set,那么您可以向您的模块添加一个方法,如下所示:

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

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

于 2018-11-24T17:29:10.503 回答