7

OneFoo と TwoFoo を Foo のリストとして Bar に挿入する必要があることを示す必要があるバインディング ステートメントは何ですか? ここでの設定は一連の責任です。現在、2 つの実装がありますが、Bar はそれを知る必要はありません。

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

しかし、Types、TypeLiteral などを使用して、2 つの 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必要に応じて の引数リストを拡張できます。同様の、しかしより冗長なアプローチは、プロバイダーを使用することです。

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 に答える