1 Reply Latest reply on Nov 25, 2013 8:49 AM by Shay Matasaro

    How to implement command pattern via CDI?

    Pasha Turok Newbie

      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 and use CDI to inject  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?

       

      I've 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> getActionMap(){

                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 <Action> 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?

        • 1. Re: How to implement command pattern via CDI?
          Shay Matasaro Newbie

          The issue with your producer is that it produces a map and not an action, therefore the action object inside will not become managed.

           

          if you want to simply replace "new"  just inject it it into the producer or the class , for example:

           

          @Produces

          @Preffered

          public HashMap<String, Action> getActionMap(SaveAction saveAction){

                    hm=new HashMap<>();

               if (...){

               hm.put("save",saveAction);

               }

               return hm;

              }