如何使用Guice模块覆盖减去绑定?

Y.H*_*ong 7 java guice

所以根据我的测试,如果你有类似的东西:

Module modA = new AbstractModule() {
    public void configure() {
        bind(A.class).to(AImpl.class);
        bind(C.class).to(ACImpl.class);
        bind(E.class).to(EImpl.class);
    }
}

Module modB = New AbstractModule() {
    public void configure() {
        bind(A.class).to(C.class);
        bind(D.class).to(DImpl.class);
    }
}

Guice.createInjector(Modules.overrides(modA, modB)); // gives me binding for A, C, E AND D with A overridden to A->C.
Run Code Online (Sandbox Code Playgroud)

但是如果你想在modB中删除E的绑定怎么办?我似乎无法找到一种方法来做到这一点,而不必将E的绑定分解为一个单独的模块.有办法吗?

Jes*_*son 10

SPI可以做到这一点.使用Elements.getElements(modA, modB)得到的列表Element对象,表示您的绑定.遍历该列表并删除您要删除其键的绑定.然后使用过滤元素创建一个模块Elements.getModule().把它们放在一起:

public Module subtractBinding(Module module, Key<?> toSubtract) {
  List<Element> elements = Elements.getElements(module);

  for (Iterator<Element> i = elements.iterator(); i.hasNext(); ) {
    Element element = i.next();
    boolean remove = element.acceptVisitor(new DefaultElementVisitor<Boolean>() { 
      @Override public <T> Boolean visit(Binding<T> binding) { 
        return binding.getKey().equals(toSubtract);
      }
      @Override public Boolean visitOther(Element other) {
        return false;
      }
    }); 
    if (remove) {
      i.remove();
    }
  }

  return Elements.getModule(elements);
}
Run Code Online (Sandbox Code Playgroud)