7

我需要告诉 guice 我想要将 OneFoo 和 TwoFoo 作为 Foo 列表注入 Bar 的绑定语句是什么?这里的设置是一个责任链。现在我有两个实现,但 Bar 不需要知道这一点。

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

但我正在努力使用 Types、TypeLiteral 等来配置两个 Foo 实现将提供给 Bar 的绑定。

4

1 回答 1

11

@Provides如果您在编译时知道绑定,则可以在模块中使用方法:

class MyModule extends AbstractModule() {
    @Override
    protected void configure() {
        // ...
    }

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

您可以foos根据需要展开 的参数列表。一个类似但更详细的方法是使用 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()));
}

在这种情况下,我再次建议使列表不可修改。

于 2013-04-23T20:44:53.210 回答