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

查看:24
本文介绍了在 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.

假设我有以下模块

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天全站免登陆