如何使用Google Guice绑定不同的界面?

时间:2010-05-08 20:55:13

标签: java dependency-injection inversion-of-control guice robot-legs-problem

我是否需要创建一个新模块,并将接口绑定到不同的实现?

Chef newChef = Guice.createInjector(Stage.DEVELOPMENT, new Module() {
     @Override
      public void configure(Binder binder) {
        binder.bind(FortuneService.class).to(FortuneServiceImpl.class);
      }

    }).getInstance(Chef.class);

Chef newChef2 = Guice.createInjector(Stage.DEVELOPMENT, new Module() {
  @Override
  public void configure(Binder binder) {
    binder.bind(FortuneService.class).to(FortuneServiceImpl2.class);
  }

}).getInstance(Chef.class);

我无法触及Chef Class和Interfaces。我只是一个客户端在运行时绑定到Chef的FortuneService到不同的接口。

3 个答案:

答案 0 :(得分:8)

看起来像Guice常见问题解答中描述的Robot Legs部分。 “如何创建一个带有两个Leg对象的机器人,左边的一个用LeftFoot注入,另一个用RightFoot注入。”但只有一个Leg类在两种情况下都被重用。

有一个PrivateModules解决方案。它使用两个独立的私有模块,一个是@Left,另一个是@Right。每个都有未注释的Foot.class和Leg.class的绑定,并为带注释的Leg.class公开绑定:

class LegModule extends PrivateModule {
  private final Class<? extends Annotation> annotation;

  LegModule(Class<? extends Annotation> annotation) {
    this.annotation = annotation;
  }

  @Override protected void configure() {
    bind(Leg.class).annotatedWith(annotation).to(Leg.class);
    expose(Leg.class).annotatedWith(annotation);

    bindFoot();
  }

  abstract void bindFoot();
}

......并将它们粘合在一起:

  public static void main(String[] args) {
    Injector injector = Guice.createInjector(
        new LegModule(Left.class) {
          @Override void bindFoot() {
            bind(Foot.class).toInstance(new Foot("leftie"));
          }
        },
        new LegModule(Right.class) {
          @Override void bindFoot() {
            bind(Foot.class).toInstance(new Foot("righty"));
          }
        });
  }

答案 1 :(得分:3)

您如何确定Chef需要哪种FortuneService实现?您无法将相同的接口绑定到不同的实现,而Guice无法区分这两者。你必须使用这样的东西。

bind(FortuneService.class).annotatedWith(Names.named("1").to(FortuneServiceImpl.class);
bind(FortuneService.class).annotatedWith(Names.named("2").to(FortuneServiceImpl2.class);

有关详细信息,请参阅here

答案 2 :(得分:0)

我认为您可以使用@Provides注释。请参阅here