What is the best way to insert a list using google-guice?

I have three classes CircleBuilder , SquareBuilder and TriangleBuilder that implement the ShapeBuilder interface.

I need to initialize my FormBuilder and, in particular, BuilderList (extension List<ShapeBuilder> ) with one instance of each class with google-guice.

What is the best way?

I know about provider methods and the like:

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

but that would mean that I need to create my FormBuilder manually, which defeats the goal of using guice (because FormBuilder is the top element in my objects graph).

I would like to write something like this:

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

Any idea?

+9
source share
2 answers

Consider Multibindings , which will collect bindings very similar to your piece of code. There are no lists for Multibinder, since Multibinder is designed to bind to the same collection in several modules, and the order of elements in the Multibinder list will depend on the order in which your modules were evaluated.

 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>. 

Alternatively, your @Provides method can take parameters (e.g. CircleBuilder or Provider<CircleBuilder> ), so you can force Guice to create everything except the list itself. Guice not only automatically binds providers of all related types, but also @Provides every parameter in any @Provides method.

 @Provides List<ShapeBuilder> provideShapeBuilders( CircleBuilder circleBuilder, SquareBuilder squareBuilder, TriangleBuilder triangleBuilder, Provider<TrapezoidBuilder> trapezoidBuilderProvider) { return new ArrayList<ShapeBuilder>( circleBuilder, squareBuilder, triangleBuilder, trapezoidBuilderProvider.get(), trapezoidBuilderProvider.get()); } 
+11
source

We can do something like this: -

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

In your FormBuilder 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); } } 
+1
source

All Articles