7 Replies Latest reply on Dec 1, 2009 1:15 PM by blabno

    Best Practices: Injection

    stormtag

      So, I have a controller which handles a single screen, part of which is listing a collection of contacts. Another part of the screen allows you to add a new contact.


      So, roughly I have something akin to this


      @In Contact contact;
      @Out List<Contact> contacts;
      
      public void addNewContact() {
         //Do some stuff
         entityManager.persist(contact);
      }
      
      @Factory("contacts")
      public void prepContacts() {
         contacts = entityManager.createQuery(...).getResultList();
      }
      



      Makes sense to me so far. Problem is that when it tries to get the contacts, it complains that there is now contact to inject.


      I can set

      @In(requires=false)

      on the contact but this seems like I'm breaking the contract for the addNewContact() method, which does require the Contact to be injected. Is there a better way to do this sort of thing? Should I have two components and lessen the cohesion?

        • 1. Re: Best Practices: Injection
          tiagoff

          Hi, my friend,


          I am new in Seam, and I had the same question for myself. :)


          To turn around this problem I created a ViewService bean which contains all independents finds.


          In your case will be something like this :


          @Name("ViewService")
          public class ViewService {
          
            @Out(required=false)
            private List<Contact> contacts;
          
            // others attributes with (required=false)
          
            @Factory("contacts")
            public void prepContacts() {
             contacts = entityManager.createQuery(...).getResultList();
            }
          
            // others factories
           
          }
          



          Maybe this is not the better approach, but solve the problem.
          I will follow this topic to see the others solutions.


          Thanks for your question.

          • 2. Re: Best Practices: Injection
            zeppelinux.dmitry.diligesoft.com

            Hi Drew,


            I'm not sure why you're injecting the Contact here, can you elaborate a bit?


            Looks like all you need is just to create a new instance (using new):




            Contact contact = new Contact();
            
            ...
            
            public void addNewContact() {
               //Do some stuff
               entityManager.persist(contact);
               contacts.add(contact);
            
               contact = new Contact()
            }
            
            



            • 3. Re: Best Practices: Injection
              stormtag

              There is a form that creates a Contact object, assigns the values to the created contact and injects it into the bean upon method invocation. The form looks something like this...


              <h:form id="addContactForm">
                   <p>Enter contact information below:</p>
                   <table>
                        <wyre:richTableInput id="firstName" value="#{contact.firstName}" label="First Name" required="true" />
                        <wyre:richTableInput id="lastName" value="#{contact.lastName}" label="Last Name" required="true" />
                              ...
                   </table>
                   <a4j:commandButton value="Add" action="#{mediaContactController.addNewContact}" .../>
              </h:form>
              



              So when the form gets submitted in AJAX, it creates the Contact object, injects it into the bean, which then does some stuff (setting non-user properties like who owns it, etc.) and persisting it.

              • 4. Re: Best Practices: Injection
                zeppelinux.dmitry.diligesoft.com

                Yes, IMHO you don't have any real reason to use injection here. 

                • 5. Re: Best Practices: Injection
                  stormtag

                  What would you suggest as an alternative?

                  • 6. Re: Best Practices: Injection
                    zeppelinux.dmitry.diligesoft.com

                    I already did, - create contact using 'new' and access it using mediaContactController object.

                    • 7. Re: Best Practices: Injection
                      blabno

                      If you have two methods running in so different cases (one should run when contact is expected, and the other should run when contact is not expected) then you should put them in separate action beans. This makes your components more fine-grained (which is neutral).