2013-06-06 2 views
1

Существует класс, который содержит некоторое состояние и реализует интерфейс. Этот класс должен быть зарегистрирован несколько раз в модуле GUICE с различными конфигурациями. Класс имеет зависимости от других bean-компонентов, которые следует вводить GUICE. Пример:Создание нескольких экземпляров класса с использованием guice

public class MenuItemImpl implements MenuItem { 
    @Inject 
    AnyService service; 

    public MenuItemImpl(String caption) { 
    this.caption = caption; 
    } 
//... 
} 

Вместо того чтобы использовать параметр c'tor публичной сеттер возможно, тоже.

В модуле Guice я хочу связать несколько экземпляров класса MenuItemImpl.

Я попытался использовать Provider<T>, однако зависимые бобы в этом случае не вводятся.

Multibinder<MenuItem> binder = Multibinder.newSetBinder(binder(), MenuItem.class); 
binder.addBinding().toProvider(new Provider<MenuItem>() { 
    @Override 
    public MenuItem get() { 
     return new MenuItemImpl("StartCaption"); 
    } 
} 

Я взглянул на аннотацию @Assist. Тем не менее, я хочу указать конфигурацию во время фазы привязки в модуле, а не при использовании компонента.

Единственным обходным решением, которое я вижу, является создание различных подклассов для каждой конфигурации, которая является плохим стилем imho, а не тем, что должно быть OO.

+1

Это обсуждается как * Robot Ножки * проблема в Guice FAQ. См. * Как создать два похожих, но немного разных дерева объектов? * В https://code.google.com/p/google-guice/wiki/FrequentlyAskedQuestions. –

+0

Спасибо за ссылку. Однако этот случай не касается разных деревьев объектов. Это больше о настройке состояния управляемых компонентов GUICE, чтобы избежать глубоких иерархий наследования. – StefanR

ответ

1
public class A 
{ 
    @Inject 
    @Named("startCaption") 
    private MenuItem menuItem; 

} 

public class B 
{ 
    @Inject 
    @Named("endCaption") 
    private MenuItem menuItem; 

} 

и в модуле Guice

String[] captions = { "startCaption", "endCaption" }; 

    for(final String caption : captions) 
    { 
     bind(MenuItem.class).annotatedWith(Names.named(caption)).toProvider(
     new Provider<MenuItem>() 
     { 
      public MenuItem get() 
      { 
       return new MenuItemImpl(caption); 
      } 

     }); 
    } 
+0

Спасибо за ваш комментарий. В моем примере мультиблок используется в качестве подключаемого механизма. Я не знаю конкретных экземпляров во время компиляции, поэтому я не могу назвать их. Код потребления будет выглядеть так: @Inject Set contribMenuItems; Кроме того, если MenuItemImpl создается внутри поставщика вручную, зависимые компоненты не вводятся. – StefanR

Смежные вопросы