2010-05-18 54 views
4

所以,根据我的测试,如果你有这样的:如何使用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. 

但是,如果你想要删除在商业方法作为E的结合?我似乎无法找到一种方法来做到这一点,而不必将E的绑定分解为单独的模块。有没有办法?

+0

只是一个愚蠢的想法,也许是的,但你尝试绑定(E.class使用)。为了(E.class使用)? (你甚至可以将接口绑定到另一个接口吗?) – 2010-05-18 04:37:03

+0

是的,只要绑定的终点指向具体的类或提供者,就可以无限期地绑定1绑定到另一个绑定。至于绑定(E.class).to(E.class),我提出了一个关于这个3年前的bug,它将在2.1中出现。 http://code.google.com/p/google-guice/issues/detail?id=171 – 2010-05-18 05:27:52

回答

9

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); 
} 
+0

哇,这确实是一个很简单的东西很多神奇的代码。它当然适用于寿。谢谢! – 2010-05-18 08:40:06

+1

如果你想要更简洁的东西,请用“instanceof Binding”和一个演员来替换访问者。我更喜欢无投弃决的方法,但最终的效果将是一样的。 – 2010-05-18 15:56:11

2

guice 4.0beta将返回只读元素列表。所以我修改Jesse Wilson的代码如下。您需要做的是提供模块列表并减去要替换的目标绑定。

Injector injector = Guice.createInjector(new TestGuiceInjectionModule(), Utils.subtractBinding(new GuiceInjectionModule(),Key.get(IInfoQuery.class))); 

功能

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

    return Elements.getModule(Collections2.filter(elements, input -> { 
     if(input instanceof Binding) 
     { 
      return !((Binding) input).getKey().equals(toSubtract); 
     } 

     return true; 
    })); 
}