Guice binding for a list of shared objects

What is a required statement that I need to tell you that I want OneFoo and TwoFoo to be entered in Bar as a list of Foo? Installation here is a chain of responsibility. Right now I have two implementations, but Bar doesn't need to know this.

@Inject
Bar(List<Foo> foos) {...}
...
class OneFoo implements Foo {
    @Inject
    OneFoo(...) {...}
...
class TwoFoo implements Foo {
    @Inject
    TwoFoo(...) {...}

But I struggle with the use of types, TypeLiteral, etc., to set up the binding where two Foo implementations will be passed to Bar.

+5
source share
1 answer

If at compile time you know the bindings, you can use the method @Providesin 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 the argument list foosas needed. A similar, but more detailed 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());
    }
}

, OneFoo TwoFoo, @Singleton. :

@Singleton
@Provides
@Inject
public List<Foo> foos(OneFoo one, TwoFoo two) {
    return Collections.unmodifiableList(Arrays.asList(one, two));
}

, , , OneFoo TwoFoo , TypeLiteral:

@Override
protected void configure() {
    bind(new TypeLiteral<List<Foo>>() {})
        .toInstance(Arrays.asList(new OneFoo(), new TwoFoo()));
}

, , .

+9

All Articles