在Guice中覆盖绑定 [英] Overriding Binding in Guice

查看:173
本文介绍了在Guice中覆盖绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用Guice,我能想到的一个用例是在测试中我只想覆盖单个绑定。我想我想使用其余的生产级绑定来确保一切正确设置并避免重复。

I've just started playing with Guice, and a use-case I can think of is that in a test I just want to override a single binding. I think I'd like to use the rest of the production level bindings to ensure everything is setup correctly and to avoid duplication.

所以想象一下我有以下模块

So imagine I have the following Module

public class ProductionModule implements Module {
    public void configure(Binder binder) {
        binder.bind(InterfaceA.class).to(ConcreteA.class);
        binder.bind(InterfaceB.class).to(ConcreteB.class);
        binder.bind(InterfaceC.class).to(ConcreteC.class);
    }
}

在我的测试中我只想覆盖InterfaceC,虽然保持InterfaceA和InterfaceB的机智,所以我想要这样的东西:

And in my test I only want to override InterfaceC, while keeping InterfaceA and InterfaceB in tact, so I'd want something like:

Module testModule = new Module() {
    public void configure(Binder binder) {
        binder.bind(InterfaceC.class).to(MockC.class);
    }
};
Guice.createInjector(new ProductionModule(), testModule);

我也试过以下,没有运气:

I've also tried the following, with no luck:

Module testModule = new ProductionModule() {
    public void configure(Binder binder) {
        super.configure(binder);
        binder.bind(InterfaceC.class).to(MockC.class);
    }
};
Guice.createInjector(testModule);

有谁知道是否可以做我想做的事情,还是我完全咆哮错误的树? ?

Does anyone know if it's possible to do what I want or am I completely barking up the wrong tree??

---跟进:
如果我在界面上使用@ImplementedBy标签然后只是我可以实现我想要的在测试用例中提供一个绑定,当接口和实现之间存在1-1映射时,它可以很好地工作。

--- Follow up: It would seem I can achieve what I want if I make use of the @ImplementedBy tag on the interface and then just provide a binding in the test case, which works nicely when there is a 1-1 mapping between the interface and implementation.

此外,在与同事讨论之后,它会看起来我们要超越整个模块并确保正确定义模块。这似乎可能会导致问题,虽然绑定在模块中放错位置并且需要移动,因此可能会破坏大量测试,因为绑定可能无法再被覆盖。

Also, after discussing this with a colleague it would seem we'd head down the road of overriding an entire module and ensuring we have our modules defined correctly. This seems like it might cause a problem though where a binding is misplaced in a module and needs to be moved, thus possibly breaking a load of tests as bindings may no longer be available to be overriden.

推荐答案

这可能不是您正在寻找的答案,但如果您正在编写单元测试,您可能不应该使用注射器而是注射手工模拟或伪造对象。

This might not be the answer you're looking for, but if you're writing unit tests, you probably shouldn't be using an injector and rather be injecting mock or fake objects by hand.

另一方面,如果你真的想要替换一个绑定,你可以使用 Modules.override( ..)

On the other hand, if you really want to replace a single binding, you could use Modules.override(..):

public class ProductionModule implements Module {
    public void configure(Binder binder) {
        binder.bind(InterfaceA.class).to(ConcreteA.class);
        binder.bind(InterfaceB.class).to(ConcreteB.class);
        binder.bind(InterfaceC.class).to(ConcreteC.class);
    }
}
public class TestModule implements Module {
    public void configure(Binder binder) {
        binder.bind(InterfaceC.class).to(MockC.class);
    }
}
Guice.createInjector(Modules.override(new ProductionModule()).with(new TestModule()));

查看详情此处

但是,由于 Modules.overrides(..)的javadoc建议,您应该以不需要覆盖的方式设计模块绑定。在您给出的示例中,您可以通过将 InterfaceC 的绑定移动到单独的模块来实现此目的。

But as the javadoc for Modules.overrides(..) recommends, you should design your modules in such a way that you don't need to override bindings. In the example you gave, you could accomplish that by moving the binding of InterfaceC to a separate module.

这篇关于在Guice中覆盖绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆