使用google-guice注入列表的最佳方法是什么?

2022-09-03 01:22:29

我有三个类,和实现接口。CircleBuilderSquareBuilderTriangleBuilderShapeBuilder

我需要用google-guice为每个类的一个实例初始化我的,特别是一个(扩展)。FormBuilderBuilderListList<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;
}

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

我希望能够写这样的东西:

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

有什么想法吗?


答案 1

考虑多重绑定,它将像收集代码片段非常相似的绑定。没有通过 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方法可以采用参数(例如 或 ),因此您可以让 Guice 创建除列表本身之外的所有内容。Guice 不仅会自动绑定所有绑定类型的提供程序,而且还会注入任何方法中的每个参数。CircleBuilderProvider<CircleBuilder>@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());
}

答案 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);
}

在您的表单生成器类中:-

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);
    }
}

推荐