来自消费包的 Guice 绑定

Guice Binding from Consumer Package

我是 Guice 的新手,正在为以下用例寻求帮助:

我开发了一个包,比如 (PCKG),其中该包的条目 class 依赖于其他 class,例如:

A : Entry point class --> @Inject A(B b) {}
B in turn is dependent on C and D like --> @Inject B(C c, D d) {}

在我的绑定模块中,我正在做:

bind(BInterface).to(Bimpl);
bind(CInterface).to(CImpl);
...

请注意,我没有为 A 提供绑定信息,因为我想由其消费者提供绑定信息 class。 (这就是设计的方式,所以我的要求是继续讨论主要问题而不是设计)。

现在我的消费者 class 正在做:

AModule extends PrivateModule {
    protected void configure() {
        bind(AInterface.class).annotatedWith(AImpl.class);
    }
}

也在我的消费包中:

.(new PCKGModule(), new AModule())

Q1。我在消费者 class 中正确地进行了绑定吗?我很困惑,因为当我在我的消费包中进行如下内部测试时:

class testModule {
    bind(BInterface).to(Bimpl); 
    bind(CInterface).to(CImpl)... 
}

class TestApp {
    public static void main(..) {
        Guice.createInstance(new testModule());
        Injector inj = Guice.createInstance(new AModule());
        A obj = inj.getInstance(A.class);
    }
}

它正在抛出 Guice 创建 exception.Please 帮助我摆脱这种情况。 我的一位朋友也对 Guice 很天真,他建议我需要使用 Provides 注释在 AModule 中创建 B 的实例。但是我真的没听懂他的意思。

您的主要方法应如下所示:

class TestApp {
public static void main(..) {
    Injector injector = Guice.createInjector(new TestModule(), new AModule());
    A obj = injector.getInstance(A.class);
}

请注意,Java 约定是 class 名称的第一个字母大写。

我很确定您对 AModule 的实施也没有按照您认为的那样进行,但是根据您提供的信息很难确定。很可能,你的意思是这样做:

bind(AInterface.class).to(AImpl.class)`

无需对 A 的绑定执行任何操作 "special"。 Guice 为您解决了所有递归问题。这是其 "magic".

的一部分

annotatedWith()to()toInstance()一起使用,像这样:

bind(AInterface.class).to(AImpl.class).annotatedWIth(Foo.class);
bind(AInterface.class).to(ZImpl.class).annotatedWIth(Bar.class);

然后您可以通过注释您的注入点来注入不同的实现,例如:

@Inject
MyInjectionPoint(@Foo AInterface getsAImpl, @Bar AInterface getsZImpl) {
    ....
}

还值得指出的是,您可以通过不使用绑定模块(取决于您的代码的排列方式)并使用 JIT 绑定来潜在地为自己节省一些样板文件:

@ImplementedBy(AImpl.class)
public interface AInterface {
    ....
}

这些有效地充当 "defaults",如果存在,它们会被显式绑定覆盖。