0 Replies Latest reply on Jul 31, 2013 7:20 AM by crewman

    Dependency injection in a factory instantiated component

    crewman Newbie

      There are two classes, Foo and Bar, implementing some interface Baz in my Seam 2.2.2 powered application. I'm trying to establish a component of Baz type conditionally implemented with one of these two classes. For this purpose I've created a factory component, BazFactory, instantiating Baz with Foo or Bar depending on a value of implClassName field:

      {code}public interface Baz {...}

       

      public class Foo implements Baz {

       

          @In

          String injectedValue1;

       

          ...

      }

       

      public class Bar implements Baz {

       

          @In

          String injectedValue2;

       

          ...

      }

       

      @Name("bazFactory")

      @Scope(value = ScopeType.SESSION)

      public class BazFactory {

       

          private String implClassName;

       

          public void setImplClassName(String implClassName) {

              this.implClassName = implClassName;

          }

       

          @Factory(value="baz", scope = ScopeType.SESSION)

          public Baz getBazImpl() throws Exception {

              Class.forName(this.implClassName).newInstance();

          }

      }{code}

      The problem is that dependencies aren't injected into instantiated class in this case. The only workaround I've devised is to declare Foo and Bar as components:

      {code}@Name("foo")

      @Scope(ScopeType.CONVERSATION)

      public class Foo implements Baz {

       

          @In

          String injectedValue1;

       

          ...

      }

       

      @Name("bar")

      @Scope(ScopeType.CONVERSATION)

      public class Bar implements Baz {

       

          @In

          String injectedValue2;

       

          ...

      }

       

      @Name("bazFactory")

      @Scope(value = ScopeType.SESSION)

      public class BazFactory {

       

          private String implComponentName;

       

          public void setImplComponentName(String implComponentName) {

              this.implComponentName = implComponentName;

          }

       

          @Factory(value="baz", scope = ScopeType.SESSION)

          public Baz getBazImpl() {

              return (Baz) Component.getInstance(this.implComponentName);

          }

      }{code}

      However, in this case there is a mess with scope types. For example, how would be scoped a component having @Scope(ScopeType.CONVERSATION) in it's declaration and scope = ScopeType.SESSION in declaration of a factory method instantiating this component (like in the example above)? Furthermore, the workaround involves creating one more component for each Baz implementation. Therefore this workaround looks ugly for me. I'd prefer to use the first way, if there were a solution to the dependency injection problem described above.

       

      Is there a way to inject dependencies into a factory instantiated component?