来自消费包的 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",如果存在,它们会被显式绑定覆盖。
我是 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",如果存在,它们会被显式绑定覆盖。