2013-04-18 23 views
5

Was ist die verbindliche Aussage, die ich Guice zu sagen, dass ich ein OneFoo und ein TwoFoo in Bar als eine Liste von Foo injiziert werden soll? Das Setup ist hier eine Kette von Verantwortung. Im Moment habe ich zwei Implementierungen, aber Bar muss das nicht wissen.Guice Binding für Liste der generischen Objekte

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

Aber ich bin zu kämpfen mit den Typen verwenden, TypeLiteral usw die Bindung, wo die beiden Foo Implementierungen gegeben wird, um Bar zu konfigurieren.

+3

Es klingt, als ob Sie [multibindings] (https://code.google.com/p/google-guice/wiki/Multibindings) verwenden möchten. –

+0

Multibindings fühlen sich zunächst wie Overkill an, da alle beteiligten Klassen unter unserer Kontrolle stehen. Aber ich werde es überprüfen, um zu sehen, wie es sich anfühlt. –

Antwort

9

Wenn Sie bei der Kompilierung der Bindungen kennen, können Sie eine @Provides Methode in Ihrem Modul verwenden:

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

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

Sie können je nach Bedarf foos ‚s Argument Liste erweitern. Ein ähnlicher, aber ausführlicher Ansatz wäre, einen Provider zu nutzen:

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()); 
    } 
} 

Falls Sie eine Singleton-Liste wollen, in dem die OneFoo und TwoFoo injiziert werden, können Sie eine @Singleton Anmerkung hinzuzufügen. Ich würde auch empfehlen die Liste machen unveränderlich an diesem Punkt:

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

Wenn auf der anderen Seite, können Sie eine Singleton Liste wollen, für die OneFoo und TwoFoo sind nicht gespritzt, können Sie eine TypeLiteral verwenden:

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

Auch in diesem Fall würde ich vorschlagen, die Liste nicht änderbar zu machen.

Verwandte Themen