Guice:绑定到绑定到其他内容的实现类型?

时间:2016-08-31 16:26:44

标签: guice

当有人要求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());

1 个答案:

答案 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