Guice:使用@Named创建对象

时间:2012-09-05 21:37:40

标签: guice

使用Guice,如果我有

@Inject @Named("light")
Color light;

我可以用

bind(Color.class).annotatedWith(Names.named("light"))
    .toInstance(new Color("white"));

如果Color构造函数只需要颜色名称,则将其绑定为白色。

但是如果Color构造函数还需要Guice创建的对象,我怎么能这样做呢?例如:

@Inject
public Color(ColorSet colorset, String colorName) {...}

其中colorset由Guice在运行时创建,并且在configure(){...}中不可用。

我想在没有的情况下这样做:

  • 为我需要注入的每种颜色创建一个类/子类(如WhiteColor)
  • 直接在我的代码中使用反射
  • 更改我的课程以使用ColorFactoy factory; factory.get("light");代替@Named("light") Color light;

3 个答案:

答案 0 :(得分:24)

执行此操作的最佳方法不是使用工厂,而是使用@Provides methods。我的公司非常非常广泛地使用Guice,requestInjection总是被认为是一个坏主意,因为它可以很容易地建立一个非常脆弱的隐式依赖图。

这是它应该是什么样子:

public class FooModule extends AbstractModule {
  protected void configure() {
    // do configuration
  }

  @Provides
  @Named("white")
  Color provideWhiteColor(ColorSet colorSet) {
    return colorSet.white(); // or whatever
  }

  @Provides
  @Named("black")
  Color provideBlackColor(ColorSet colorSet) {
    return colorSet.black(); // or whatever
  }

  // etc
}

答案 1 :(得分:2)

您可以在模块中设置工厂,并请求在其上注入以填充ColorSet。

模块:

ColorFactory colorFactory = new ColorFactory();

requestInjection(colorFactory);

bind(Color.class).annotatedWith(Names.named("light")).toInstance(colorFactory.buildColor("white"));
bind(Color.class).annotatedWith(Names.named("dark")).toInstance(colorFactory.buildColor("black"));

ColorFactory:

public class ColorFactory {

    private ColorSet colorSet;

    public Color buildColor(String color){
        return new Color(colorSet, color);
    }

    @Inject
    public void setColorSet(ColorSet colorSet) {
        this.colorSet = colorSet;
    }
}

答案 2 :(得分:0)

在很少的代码库中,我看到直接使用注射器来获取某些对象。

injector.getInstance(Color.class);

在这种情况下,您可以使用以下内容:

injector.getInstance(Key.get(Color.class, Names.named("light")));