Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inject list of objects in CDI (Weld)

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.

like image 618
Bozho Avatar asked Oct 24 '10 17:10

Bozho


People also ask

What does the@ inject annotation do?

The @Inject annotation lets us define an injection point that is injected during bean instantiation. Injection can occur via three different mechanisms. A bean can only have one injectable constructor. A bean can have multiple initializer methods.

How do you make a class injectable in Java?

In order to inject class it should be: Concrete class (i.e not abstract or interface) or it should annotated as @Decorator. Should have no-arg constructor or constructor annotated with @Inject. Should not have annotated with an EJB component-defining annotation or declared as an EJB bean class in ejb-jar.

What does javax inject do?

Package javax. inject Description. This package specifies a means for obtaining objects in such a way as to maximize reusability, testability and maintainability compared to traditional approaches such as constructors, factories, and service locators (e.g., JNDI).

What is CDI interface?

Live Chat. AWS Cloud Digital Interface (AWS CDI) is a network technology that allows you to transport high-quality uncompressed video inside the AWS Cloud, with high reliability and network latency as low as 8 milliseconds.


1 Answers

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) {..} 
like image 145
Bozho Avatar answered Sep 22 '22 13:09

Bozho