2013-04-18 52 views
5

Tuyên bố ràng buộc là gì tôi cần nói với guice rằng tôi muốn một OneFoo và một TwoFoo được tiêm vào Bar như một Danh sách Foo? Việc thiết lập ở đây là một chuỗi trách nhiệm. Ngay bây giờ tôi có hai triển khai, nhưng Bar không cần phải biết điều đó.Ràng buộc Guice cho Danh sách các đối tượng chung

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

Nhưng tôi đang đấu tranh với việc sử dụng các loại, TypeLiteral, v.v ... để định cấu hình ràng buộc nơi triển khai Foo sẽ được cung cấp cho Bar.

+3

Có vẻ như bạn muốn sử dụng [multibindings] (https://code.google.com/p/google-guice/wiki/Multibindings). –

+0

multibindings ban đầu cảm thấy như overkill vì tất cả các lớp học liên quan là dưới sự kiểm soát của chúng tôi. Nhưng tôi sẽ kiểm tra xem nó cảm thấy thế nào. –

Trả lời

9

Nếu bạn biết tại thời gian biên dịch các ràng buộc, bạn có thể sử dụng một phương pháp @Provides trong module của bạn:

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

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

Bạn có thể mở rộng danh sách đối số foos 's khi cần thiết. Một cách tiếp cận tương tự, nhưng tiết hơn, sẽ được sử dụng một nhà cung cấp:

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

Trong trường hợp bạn muốn có một danh sách singleton trong đó OneFoo và TwoFoo đang tiêm, bạn có thể thêm chú thích @Singleton. Tôi muốn giới thiệu cũng làm cho danh sách không thay đổi tại thời điểm đó:

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

Nếu mặt khác, bạn muốn có một danh sách singleton mà OneFoo và TwoFoo KHÔNG tiêm, bạn có thể sử dụng một TypeLiteral:

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

Trong trường hợp này quá, một lần nữa, tôi muốn đề nghị làm cho danh sách không thể sửa đổi.

Các vấn đề liên quan