简体   繁体   中英

Guice Binding for List of generic Objects

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM