2013-04-18 17 views
5

Co to jest wiążące oświadczenie, które muszę powiedzieć, że chcę, aby OneFoo i TwoFoo zostały wprowadzone do paska jako lista Foo? Konfiguracja jest tutaj łańcuchem odpowiedzialności. W tej chwili mam dwie implementacje, ale Bar nie musi tego wiedzieć.Wiązanie Guice na listę ogólnych obiektów

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

Ale mam zmaga się z wykorzystaniem typów TypeLiteral itp skonfigurować wiązanie gdzie dwie implementacje Foo będą podane do baru.

+3

Wygląda na to, że chcesz użyć opcji [multibinding] (https://code.google.com/p/google-guice/wiki/Multibindings). –

+0

W wielu przypadkach początkowo odczuwamy przesadę, ponieważ wszystkie zajęcia są pod naszą kontrolą. Ale sprawdzę to, żeby zobaczyć, jak to jest. –

Odpowiedz

9

Jeśli wiesz, w czasie kompilacji powiązań, można użyć metody @Provides w module:

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

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

Można poszerzyć listę argumentów foos „s, ile potrzeba. Podobny, ale bardziej gadatliwy podejście byłoby użyć 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()); 
    } 
} 

W przypadku, gdy chcesz listę singleton w którym OneFoo i TwoFoo są wstrzykiwane, można dodać @Singleton adnotacji. Polecam także sporządzaniu listy niezmienna w tym punkcie:

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

Jeśli z drugiej strony chcesz singleton listy, dla których OneFoo i TwoFoo NIE są wstrzykiwane, można wykorzystać do TypeLiteral:

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

Również w tym przypadku sugeruję, aby lista była niemodyfikowalna.

Powiązane problemy