I am newbie in CDI and a little bit confused. I have the following problem. We have class Action. And we have wrapper class that keeps all Action objects in hashmap. Something like this.
class TestAction implements Action{
@EJB
private MyBean bean;
public void doSomething(){
//here we do something with injected EJB
}
}
class Foo {
private HashMap<String, Action> hm;
public void execute (String action){
this.hm.get(action).doSomething();
}
}
When I don't use CDI - everything is ok. But I need to use it. So, as I understand I must create all my actions via cdi container otherwise CDI container can't inject managed beans into them. So my question what is the best way to implement command pattern via CDI?
EDITED: I read Dependency Injection by Dhanji R. Prasanna, Weld-reference(WR), JavaEE7 tutorial (CDI part) - don't recommend to read the last. After thinking a little bit I understood that I need to inject HashMap. Besides, I understood that I have to use producer methods. Ok. I said. Finally I got it. So I wrote the following producer method:
@ApplicationScoped
public class ActionMapFactory {
@Produces @Preffered
public HashMap<String, Action> getHashMap(){
HashMap<String, Action> hm=new HashMap<>();
if (...){
hm.put("save",new SaveAction());
}
return hm;
}
}
From WR:
There's one potential problem with the code above. The implementations of are instantiated using the Java new operator. Objects instantiated directly by the application can't take advantage of dependency injection and don't have interceptors.
I have read the solution from WR, but what should I do if I have dozens of actions and a lot child classes of Foo?
You could avoid
new
by injecting all actions intoActionMapFactory
and populate theHashMap
at the producer method:If you don't want to keep those
Action
instances as attributes, do a constructor injection: