16

我有三个类CircleBuilderSquareBuilderTriangleBuilder实现ShapeBuilder接口。

我需要使用 google-guice 用每个类的一个实例初始化我的FormBuilder,特别是一个BuilderList(扩展)。List<ShapeBuilder>

什么是最好的方法?

我知道提供程序的方法和类似的东西:

@Provides
FormBuilder provideFormBuilder() {
    DatabaseTransactionLog instance = new FormBuilder ( <numerous parameters> );

    ShapeBuilder builder = null ; 
    builder = new CircleBuilder( <numerous parameters> ) ;  
    instance.addBuilder( builder ) ;

    builder = new SquareBuilder( <numerous parameters> ) ;  
    instance.addBuilder( builder ) ;

    // And so on

    return instance;
}

但这意味着我必须FormBuilder手动创建,这违背了使用 guice 的目的(因为FormBuilder是我的对象图中的顶部元素)。

我很想能够写出这样的东西:

bind(BuilderList.class).to(CircleBuilder.class);
bind(BuilderList.class).to(TriangleBuilder.class);
bind(BuilderList.class).to(SquareBuilder.class);

任何的想法?

4

2 回答 2

21

考虑Multibindings,它将非常像您的代码片段那样收集绑定。没有通过 Multibinder 提供列表,因为 Multibinder 旨在绑定到多个模块中的同一集合,并且 Multibinder 列表的元素顺序将取决于您的模块被评估的顺序。

Multibinder<ShapeBuilder> shapeBinder =
    Multibinder.newSetBinder(binder(), ShapeBuilder.class);
shapeBinder.addBinding().to(CircleBuilder.class);
shapeBinder.addBinding().to(TriangleBuilder.class);
shapeBinder.addBinding().to(SquareBuilder.class);

// Now you can inject Set<ShapeBuilder>.

或者,您的@Provides方法可以接受参数(例如CircleBuilderProvider<CircleBuilder>),这样您就可以让 Guice 创建除 List 本身之外的所有内容。Guice 不仅会自动绑定所有绑定类型的 Provider,而且还会在任何@Provides方法中注入每个参数。

@Provides List<ShapeBuilder> provideShapeBuilders(
    CircleBuilder circleBuilder,
    SquareBuilder squareBuilder,
    TriangleBuilder triangleBuilder,
    Provider<TrapezoidBuilder> trapezoidBuilderProvider) {
  return new ArrayList<ShapeBuilder>(
      circleBuilder,
      squareBuilder,
      triangleBuilder,
      trapezoidBuilderProvider.get(),
      trapezoidBuilderProvider.get());
}
于 2013-01-07T22:33:38.570 回答
2

我们可以这样做:-

@Override
protected void configure() {
    bind(ShapeBuilder.class).annotatedWith(Names.named("Circle")).to(CircleBuilder.class);
    bind(ShapeBuilder.class).annotatedWith(Names.named("Triangle")).to(TriangleBuilder.class);
    bind(ShapeBuilder.class).annotatedWith(Names.named("Square")).to(SquareBuilder.class);
}

在您的 FormBuilder 类中:-

class FormBuilder{
   List<ShapeBuilder> shapeBuilderList;
   @Inject
   public FormBuilder(@Named("Circle")ShapeBuilder circle, @Named("Triangle")ShapeBuilder triangle,@Named("Square")ShapeBuilder square){
       shapeBuilderList = new ArrayList<>();
       //add all of them
       shapeBuilderList.add(circle);
    }
}
于 2017-03-22T00:48:11.330 回答