7 Replies Latest reply on Jan 28, 2016 5:49 AM by mkouba

    How to dynamically build independent object trees ?

    matiouz

      Hi all,

      I'm wondering how to use CDI to build multiple independent objects trees representing the same type of data. Here is an example:

      I have a Car, in which I want to inject GearShift and Engine.
      I also want to inject Engine in GearShift

      This Car + GearShift + Engine is my tree.

      If I want to have several cars at the same time, what would be the best way to do this using CDI?
      I would expect to be able to define a kind of scope or a qualifier for each tree. But CDI scopes and qualifiers are defined statically, while the number of cars is dynamic.

      As an additional requirement, I would like to inject another dependency that would be shared between cars. For example, all cars would share the same Road for their whole lifetime (couldn't find something else that makes more sense).

      Thanks in advance

        • 1. Re: How to dynamically build independent object trees ?
          mkouba

          Hi Mathieu,

          you could make use of Programmatic lookup together with built-in @Dependent pseudo scope (or use a custom scope which better reflects the lifecycle of your beans). For shared beans (like Road) a built-in @ApplicationScoped should work.

          @Inject Instance<Car> carInstance;
          
          void foo() {
            // Every time you call get() a new instance of Car is created - the same applies to GearShift and Engine (provided all the beans are @Dependent)
            Car car1 = carInstance.get();
            Car car2 = carInstance.get()
            // Don't forget to destroy the dependent instances properly
            carInstance.destroy(car1);
            carInstance.destroy(car2);
          }
          
          • 2. Re: How to dynamically build independent object trees ?
            matiouz

            Hi Martin,

            thanks for your answer

            But then, how to have a GearShift that is shared between the Car and Engine of the same tree?

            If I inject GearShift in Car and Engine using a Dependent scope, the Car and the Engine of the same tree will each have a different GearShift?

            Thanks again

            • 3. Re: How to dynamically build independent object trees ?
              mkouba
              If I inject GearShift in Car and Engine using a Dependent scope, the Car and the Engine of the same tree will each have a different GearShift?

              Yes, there will be two different instances. There is no built-in scope which could be used here - @ApplicationScoped is shared accross the whole application (i.e. nothing like "object graph scope"). If you want to reuse a GearShift injected into the Car, then you'll have to pass a reference to the Engine manually.

              • 4. Re: How to dynamically build independent object trees ?
                matiouz

                Thanks Martin

                I actually asked this because I often read that DI frameworks were able to replace factories. But it seems that for this use case, it's not possible (yet?).

                Just out of curiosity, does anyone know if other DI frameworks allow this? Guice?

                • 5. Re: How to dynamically build independent object trees ?
                  mkouba

                  Actually, it might be feasible using a custom scope and @AroundConstruct interceptor. If I have some spare time I will try to create a prototype. I don't think Guice or Dagger2 provide a built-in scope for this use case.

                  • 6. Re: How to dynamically build independent object trees ?
                    mkouba

                    Hi Mathieu, if you have some time take a look at this repo: mkouba/tree-context · GitHub. I've tried to implement an "object tree context". There is a test which shows the usage of a custom scope @TreeDependent. I'm curious whether this is what you were looking for.

                    • 7. Re: How to dynamically build independent object trees ?
                      mkouba

                      A colleague of mine pointed out (thanks Matej :-) that it's not possible to inject a @TreeDependent bean into a bean with other than @Dependent or @TreeDependent scope.