2010-10-24 5 views
33

Предположим, у меня есть интерфейс под названием SocialNetworkService, а три варианта реализации - TwitterService, FacebookService и FriendFeedService.Инъекционный список объектов в CDI (Weld)

Теперь я хочу, всякий раз, когда мой управляемый компонент (или любой другой веб-компонент) получает сообщение, делиться им во всех социальных сетях. Я пробовал:

@Inject private List<SocialNetworkService> socialNetworkServices; 

Но это не сработало (ошибка развертывания). (Также пытался определить @Any - тот же результат)

Итак, есть ли способ внедрить список всех (или некоторых) реализаций интерфейса?

Я знаю правило, что данная точка инъекции не должна иметь более одного возможного компонента. Наверное, я могу добиться этого, создав производителя, который создает список, и используя Instance<SocialNetworkService>, но это слишком похоже на эту задачу.

+0

Хотите оставаться чистой JSR-330? –

+0

330 и 299 .. Это должно быть достаточно – Bozho

ответ

55

Объединяя мои попытки найти ответ с форума Weld:

@Inject @Any 
private Instance<SocialNetworkService> services; 

Instance реализует Iterable, так что тогда можно просто использовать для-каждый цикл. Необходим квалификатор @Any.


Другой способ сделать это с помощью системы событий:

  • создать MessageEvent (содержащий всю информацию о сообщении)
  • вместо инъекционного список социальных сетей, просто впрыснуть событие:

    @Inject private Event<MessageEvent> msgEvent; 
    

    и стрелять: msgEvent.fire(new MessageEvent(message));

  • наблюдать событие во всех услуг (независимо от их интерфейса, который может быть плюс):

    public void consumeMessageEvent(@Observes MessageEvent msgEvent) {..} 
    
+0

Интересно (+1) –

+2

+1 Это пойдет в мой список анти-шаблонов CDI! – Tair

+0

@tiar - почему анти-шаблоны? – Bozho

0

Я посмотрел спецификацию JSR-299, и, похоже, вы не можете делать то, что хотите сделать легко, и у меня нет опыта с Weld для предоставления кода для этого особого случая.

Однако, на основании главы 12.3 «Обнаружение бинов» вы можете объявить реализации как @ Alternative (чтобы избежать жалобы Weld о нескольких реализациях) и прослушивать события ProcessBean для сбора, когда видны реализации SocialNetworkService.

+0

, что было бы еще более утомительно, чем мое первоначальное предложение. Спасибо, в любом случае. – Bozho

+0

Исходное предложение по-прежнему необходимо знать обо всех ваших реализациях - Weld не может, насколько я могу вам сказать. –