2013-04-18 4 views
5

Guiceに私にOneFooとTwoFooをFooのListとして注入したいと言うのに必要なバインディングステートメントは何ですか?ここでの設定は責任の連鎖です。今は2つの実装がありますが、Barはそれを知る必要はありません。一般オブジェクトのリストのためのGuiceバインディング

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

しかし、私は2つのFooの実装がバーに与えられますどこバインディングを設定するには、種類、TypeLiteralなどを使用して苦労しています。あなたはコンパイル時にバインディングを知っていれば

+3

あなたは[multibindings](https://code.google.com/p/google-guice/wiki/Multibindings)を使いたいと思うようです。 –

+0

multibindingsは当初、関係するすべてのクラスが私たちのコントロール下にあるので、過剰な気分になりました。しかし、私はそれがどのように感じるか見るためにそれをチェックアウトします。 –

答えて

9

は、あなたのモジュールで@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注釈を追加することができます。一方で、あなたはOneFooとTwoFooが注入されていないため、シングルトンリストが必要な場合は

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

、あなたが使用することができTypeLiteralを:私はその時点で不変のリストを作るにも推薦する

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

この場合も、リストを変更不可能にすることを提案します。