2013-06-07 38 views
5

Tôi có đoạn mã sau sử dụng bindings Guice:Guice: Ràng buộc một số đối tượng với sự phụ thuộc khác nhau

public class MyApplication { 
    public static void main(String[] args) { 
     Guice.createInjector(new AbstractModule() { 
      @Override 
      protected void configure() { 
       bind(Foo.class).annotatedWith(Names.named("first")).toInstance(new Foo("firstFoo")); 
       bind(Foo.class).annotatedWith(Names.named("second")).toInstance(new Foo("secondFoo")); 

       bind(Bar.class).to(BarImpl.class); 

       bind(MyApplication.class).asEagerSingleton(); 
      } 
     }); 
    } 

    private @Named("first") Bar first; 
    private @Named("second") Bar second; 

    static @Value class Foo { String name; } 
    static interface Bar {} 

    static class BarImpl implements Bar { 
     @Inject @Named Foo foo; 
    } 
} 

Tôi đang cố gắng để có được một đối tượng Bar cho cả tên Foo s tiêm trong ứng dụng của tôi. Về cơ bản, nó bằng cách nào đó sẽ kết nối các @Named trên Foo với một trên Bar. Tôi đã thử một số giải pháp, từ việc đặt @Named lên mọi thứ để viết một tùy chỉnh Provider. Cái sau không hoạt động vì tôi không có quyền truy cập vào giá trị của chú thích @Named bên trong nhà cung cấp. Tôi nghĩ rằng giải pháp là một nơi nào đó trong dòng bind(Bar.class).to(BarImpl.class);, nói với nó để nhớ giá trị của chú thích @Named.

Câu hỏi của tôi là, điều này có thể xảy ra hay không và nếu có thì làm cách nào?

Trả lời

10

Đang sử dụng PrivateModules. Về cơ bản:

Thông tin cấu hình của mô-đun riêng được ẩn khỏi môi trường theo mặc định. Chỉ các ràng buộc được hiển thị rõ ràng sẽ có sẵn cho các mô-đun khác và cho người dùng của bộ phun. Để được giải thích thêm, hãy xem this FAQ entry.

Đây là cách bạn muốn sử dụng nó:

protected void configure() { 
    install(new PrivateModule() { 
     @Override 
     protected void configure() { 
      // #bind makes bindings internal to this module unlike using AbstractModule 
      // this binding only applies to bindings inside this module 
      bind(Foo.class).toInstance(new Foo("first")); 
      // Bar's foo dependency will use the preceding binding 
      bind(Bar.class).annotatedWith(Names.named("first")).to(BarImpl.class); 
      // if we'd stop here, this would be useless 
      // but the key method here is #expose 
      // it makes a binding visible outside as if we did AbstractModule#bind 
      // but the binding that is exposed can use "private" bindings 
      // in addition to the inherited bindings    
      expose(Bar.class).annotatedWith(Names.named("first")); 
     } 
    }); 
    install(new PrivateModule() { 
     @Override 
     protected void configure() { 
      bind(Foo.class).toInstance(new Foo("second")); 
      bind(Bar.class).annotatedWith(Names.named("second")).to(BarImpl.class); 
      expose(Bar.class).annotatedWith(Names.named("second")); 
     } 
    }); 
     bind(MyApplication.class).asEagerSingleton(); 
    } 
} 

Bây giờ bạn có hiệu quả có 2 Bars mỗi trong số đó trông giống như

static class BarImpl implements Bar { 
    @Inject Foo foo; 
} 

nhưng với sức mạnh của PrivateModules có một thực hiện khác nhau ràng buộc cho cùng một sự phụ thuộc.

Hy vọng điều đó có ý nghĩa.

+0

Cảm ơn, điều này có vẻ đầy hứa hẹn. Tôi sẽ thử nó vào thứ hai. – Jorn

+1

Có, điều này đã giải quyết được vấn đề của tôi. Cảm ơn một lần nữa! – Jorn

+0

Bạn được chào đón! –

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