views:

27

answers:

2

Let's say I have an interface called SocialNetworkService, and three implementations - TwitterService, FacebookService and FriendFeedService.

Now I want, whenever my managed bean (or whatever web component) receives a message, to share it in all social networks. I tried:

@Inject private List<SocialNetworkService> socialNetworkServices;

But it didn't work (deployment error). (Also tried to the @Any qualifier - same result)

So, is there a way to inject a list of all (or some) implementations of an interface?

I know the rule that a given injection point should not have more than one possible bean. I guess I can achieve that by making a producer that produces the list, and using Instance<SocialNetworkService>, but that seems like too much for this task.

A: 

I had a look at the JSR-299 specification and it doesn't seem that you can do what you want to do easily and I do not have experience enough with Weld to provide code for this special case.

However, based on chapter 12.3 "Bean Discovery" you might be able to declare the implementations as @Alternative's (to avoid Weld complain about multiple implementations) and listen to ProcessBean events to collect when implementations of SocialNetworkService are seen.

Thorbjørn Ravn Andersen
that would be even more tedious than the my initial suggestion. Thanks anyway.
Bozho
The initial suggestion still needs to know about all your implementations - Weld cannot as far as I can see tell you.
Thorbjørn Ravn Andersen
A: 

Combining my attempts with an answer from the Weld forum:

@Inject @Any
private Instance<SocialNetworkService> services;

Instance implements Iterable, so it is then possible to simply use the for-each loop. The @Any qualifier is needed.


Another way to do this is by using the event system:

  • create a MessageEvent (containing all the information about the message)
  • instead of injecting a list of social networks, simply inject the event:

    @Inject private Event<MessageEvent> msgEvent;
    

    and fire it: msgEvent.fire(new MessageEvent(message));

  • observe the event in all services (regardless of their interface, which might be a plus):

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