【问题标题】:What is the best way to inject a list with google-guice?用 google-guice 注入列表的最佳方法是什么?
【发布时间】:2013-01-07 20:41:48
【问题描述】:

我有三个类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);

有什么想法吗?

【问题讨论】:

    标签: java dependency-injection guice


    【解决方案1】:

    考虑Multibindings,它将收集绑定非常类似于您的代码sn-p。没有通过 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>.
    

    另外,your @Provides method 可以接受参数(例如CircleBuilderProvider&lt;CircleBuilder&gt;),因此您可以让 Guice 创建除列表本身之外的所有内容。 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());
    }
    

    【讨论】:

    • 注意:多重绑定需要另一个 jar -> guice-multibindings-3.0.jar
    • 我的问题(我在这里包括的 url)展示了如何使用 Mulitbinder,然后将混凝土的“集合”注入需要它们的类(对于那些倾向于基于构造函数的注入的人) . stackoverflow.com/questions/52279459/…
    • 这是 Multibindings 用户指南的当前链接:github.com/google/guice/wiki/Multibindings
    • @UzielSulkies 六年过得真快!我已经更新了两个链接。感谢您的 ping!
    【解决方案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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-12-15
      • 1970-01-01
      • 2022-09-23
      • 2010-09-07
      • 2020-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多