What is the binding statement I need to tell guice to that I want a OneFoo and a TwoFoo injected into Bar as a List of Foo? The setup here is a chain of responsibility. Right now I have two implementations, but Bar doesn't need to know that.
@Inject
Bar(List<Foo> foos) {...}
...
class OneFoo implements Foo {
@Inject
OneFoo(...) {...}
...
class TwoFoo implements Foo {
@Inject
TwoFoo(...) {...}
But I'm struggling with using the Types, TypeLiteral, etc to configure the binding where the two Foo implementations will given to Bar.
If you know at compile time the bindings, you can use an @Provides
method in your module:
class MyModule extends AbstractModule() {
@Override
protected void configure() {
// ...
}
@Provides
@Inject
public List<Foo> foos(OneFoo one, TwoFoo two) {
return Arrays.asList(one, two);
}
}
You can expand foos
's argument list as needed. A similar, but more verbose approach, would be to use a Provider:
protected void configure() {
bind(new TypeLiteral<List<Foo>>() {})
.toProvider(FooListProvider.class);
}
static class FooListProvider implements Provider<List<Foo>> {
@Inject
Provider<OneFoo> one;
@Inject
Provider<TwoFoo> two;
public List<Foo> get() {
return Arrays.asList(one.get(), two.get());
}
}
In case you want a singleton list in which the OneFoo and TwoFoo are injected, you can add an @Singleton
annotation. I would recommend also making the list immutable at that point:
@Singleton
@Provides
@Inject
public List<Foo> foos(OneFoo one, TwoFoo two) {
return Collections.unmodifiableList(Arrays.asList(one, two));
}
If on the other hand, you want a singleton list for which OneFoo and TwoFoo are NOT injected, you can use a TypeLiteral:
@Override
protected void configure() {
bind(new TypeLiteral<List<Foo>>() {})
.toInstance(Arrays.asList(new OneFoo(), new TwoFoo()));
}
In this case too, again, I'd suggest making the list unmodifiable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With