当有人要求Thing
时,我想给他们一个LegacyThing
。但如果他们要求@Modern Thing
,那么我想给他们Thing
本身。
这不起作用:
bind(Thing.class).to(LegacyThing.class);
bind(Thing.class).annotatedWith(Modern.class).to(Thing.class);
因为第二个绑定链接到第一个绑定,而不是直接链接到Thing
。
如何将Thing
作为实现绑定,而不是绑定到另一个绑定?
我不想自己实例化Thing
,因为它有很多我希望注入器处理的依赖项。我也不愿意将其子类化或从中提取界面,因为这也会很混乱。
我提出的最好的想法是使用构造函数绑定,但它感觉很hacky:
bind(Thing.class)
.annotatedWith(Modern.class)
.toConstructor((Constructor<Thing>) InjectionPoint.forConstructorOf(Thing.class)
.getMember());
答案 0 :(得分:0)
您可以使用方法提供程序来执行此操作。你说你不想自己创建实例,但另一方面,当你在super()
中调用LegacyThing
时,你已经做了那么多的工作。只需复制/粘贴。或直接注入字段。
import com.google.inject.*;
import java.lang.annotation.*;
public class Test {
static class Dependency {}
static class Thing {
@Inject Thing(Dependency dependency) {}
}
static class LegacyThing extends Thing {
@Inject LegacyThing(Dependency dependency) { super(dependency); }
}
static class Holder {
@Inject @Modern Thing modern;
@Inject Thing legacy;
}
@BindingAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
static @interface Modern { }
public static void main(String[] args) {
Holder holder = Guice.createInjector(new AbstractModule() {
@Provides @Modern Thing provideModernThing(Dependency dependency) {
return new Thing(dependency);
}
@Provides Thing provideLegacyThing(Dependency dependency) {
return new LegacyThing(dependency);
}
@Override protected void configure() {
bind(Dependency.class).in(Singleton.class);
}
}).getInstance(Holder.class);
System.out.printf("Modern: %s%n", holder.modern.getClass().getName());
System.out.printf("Legacy: %s%n", holder.legacy.getClass().getName());
}
}
结果:
Modern: Test$Thing Legacy: Test$LegacyThing