Guice 根据父实例注解注入不同的实例
Guice inject different instance based on the parent instance annotation
我在我的应用程序中使用了 guice 框架。我有一个场景,其中单个 class 可能需要相同接口 C 的多个实例(但出于不同目的),如示例所示。我正在尝试使用 guice 中的注释工具解决这个问题。
如下例所示,我希望ConcreteImpl的配置也通过guice注入。但问题是 type1、type2 和 type3 实例的配置可能不同。假设我有这些实例的先验配置,是否有一种工具可以根据请求配置的实例的上下文(由注释表示)注入它们?
class A {
@Inject
public A(@Purpose1 C type1, @Purpose2 C type2, @Purpose3 C type3) {
}
}
interface C {}
class ConcreteImpl implements C {
@Inject
public ConcreteImpl(ConcreteImplConfig config) {}
}
class ConcreteImplConfig {
String pty1;
String pty2;
}
我的模块绑定是这样的 -
bind(C.class)
.annotatedWith(Purpose1.class)
.to(purpose1Cklass/**obtained from config**/);
bind(C.class)
.annotatedWith(Purpose2.class)
.to(purpose2Cklass/**obtained from config**/);
bind(C.class)
.annotatedWith(Purpose3.class)
.to(purpose3Cklass/**obtained from config**/);
这正是我想做的事情
bind(ConcreteImplConfig.class)
.requestedThrough(Purpose1.class)
.toInstance(purpose1config);
bind(ConcreteImplConfig.class)
.requestedThrough(Purpose2.class)
.toInstance(purpose2config);
bind(ConcreteImplConfig.class)
.requestedThrough(Purpose3.class)
.toInstance(purpose3config);
我已经看过辅助注入,它可以注入一个工厂,然后我们使用 factory.create(config),但我不倾向于那样做,因为合同往往会变得有点丑陋,而且更多我在我的应用程序开始时拥有所有配置,应该能够注入它们。
这是 C 的 Robot Leg Problem. You need to create a private module。
abstract class CModule extends PrivateModule {
private final Class<? extends Annotation> annotation;
CModule(Class<? extends Annotation> annotation) {
this.annotation = annotation;
}
@Override protected void configure() {
bind(C.class).annotatedWith(annotation).to(C.class);
expose(C.class).annotatedWith(annotation);
bindConfig();
}
abstract void bindConfig();
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(
new CModule(Propsal1.class) {
@Override void bindConfig() {
bind(ConcreteImplConfig.class).toInstance(new ConcreteImplConfig());
}
},
new CModule(Propsal2.class) {
@Override void bindConfig() {
bind(ConcreteImplConfig.class).toInstance(new ConcreteImplConfig());
}
},
new CModule(Propsal2.class) {
@Override void bindConfig() {
bind(ConcreteImplConfig.class).toInstance(new ConcreteImplConfig());
}
}
);
}
我在我的应用程序中使用了 guice 框架。我有一个场景,其中单个 class 可能需要相同接口 C 的多个实例(但出于不同目的),如示例所示。我正在尝试使用 guice 中的注释工具解决这个问题。
如下例所示,我希望ConcreteImpl的配置也通过guice注入。但问题是 type1、type2 和 type3 实例的配置可能不同。假设我有这些实例的先验配置,是否有一种工具可以根据请求配置的实例的上下文(由注释表示)注入它们?
class A {
@Inject
public A(@Purpose1 C type1, @Purpose2 C type2, @Purpose3 C type3) {
}
}
interface C {}
class ConcreteImpl implements C {
@Inject
public ConcreteImpl(ConcreteImplConfig config) {}
}
class ConcreteImplConfig {
String pty1;
String pty2;
}
我的模块绑定是这样的 -
bind(C.class)
.annotatedWith(Purpose1.class)
.to(purpose1Cklass/**obtained from config**/);
bind(C.class)
.annotatedWith(Purpose2.class)
.to(purpose2Cklass/**obtained from config**/);
bind(C.class)
.annotatedWith(Purpose3.class)
.to(purpose3Cklass/**obtained from config**/);
这正是我想做的事情
bind(ConcreteImplConfig.class)
.requestedThrough(Purpose1.class)
.toInstance(purpose1config);
bind(ConcreteImplConfig.class)
.requestedThrough(Purpose2.class)
.toInstance(purpose2config);
bind(ConcreteImplConfig.class)
.requestedThrough(Purpose3.class)
.toInstance(purpose3config);
我已经看过辅助注入,它可以注入一个工厂,然后我们使用 factory.create(config),但我不倾向于那样做,因为合同往往会变得有点丑陋,而且更多我在我的应用程序开始时拥有所有配置,应该能够注入它们。
这是 C 的 Robot Leg Problem. You need to create a private module。
abstract class CModule extends PrivateModule {
private final Class<? extends Annotation> annotation;
CModule(Class<? extends Annotation> annotation) {
this.annotation = annotation;
}
@Override protected void configure() {
bind(C.class).annotatedWith(annotation).to(C.class);
expose(C.class).annotatedWith(annotation);
bindConfig();
}
abstract void bindConfig();
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(
new CModule(Propsal1.class) {
@Override void bindConfig() {
bind(ConcreteImplConfig.class).toInstance(new ConcreteImplConfig());
}
},
new CModule(Propsal2.class) {
@Override void bindConfig() {
bind(ConcreteImplConfig.class).toInstance(new ConcreteImplConfig());
}
},
new CModule(Propsal2.class) {
@Override void bindConfig() {
bind(ConcreteImplConfig.class).toInstance(new ConcreteImplConfig());
}
}
);
}