4 Replies Latest reply on Sep 1, 2011 9:34 AM by kcbabo

    Context injection for bean services

    kcbabo

      Reading through the docs for 0.2, it occurred to me that we may need to enhance the bean context injection support.  Right now, it works nicely for @Service beans - you can grab the exchange, in, and out context properties for any invocation of the bean service.  What's missing is the ability to set context properties for services that are being invoked through an @Reference.  Thought I would start a thread to discuss how we might enhance the current support to provide this feature - assuming everyone agrees it's a good idea. :-)

       

      My first thought is that we could add an annotation element which identifies the service to which the context is bound.  The default case is the same for @Service - we simply assume that if no annotation elements are present, it refers to the @Serivce of the bean itself:

       

      @Inject
      private Context context;
      

       

      In the case of a reference, we can pass in something like the interface class or service name to bind an injected instance of a context to a specific @Reference:

       

      @Inject @Reference
      private SomeService someService;
      
      @Inject @ServiceContext(SomeService.class)
      private Context someServiceContext;
      

       

      The fact that we need to add another annotation is a bit sucky, but I can't think of a way around that and it's not totally horrible.

       

      Thoughts?

        • 1. Re: Context injection for bean services
          tfennelly

          I too am trying to think is there another approach.. the @ServiceContext annotation isn't too bad at all on its own, but something does feel strange (for me) about it in the context of the wider picture/usage... injecting a context instance for an Exchange that doesn't even exist yet (might never exist... depending on the logic).  Just seems a bit funky to me.

          • 2. Re: Context injection for bean services
            kcbabo

            The only other two methods I could think of were:

             

            (a) Create a wrapped type for injected references which has a getter for the service interface and the context.  People that need to set/get context properties would inject this instead of the service interface.

             

            @Inject @Reference
            private ServiceReference myService;
            

             

            public interface ServiceReference {
               <T> T getInterface();
                Context getContext();
            }
            

             

            (b) Add a ServiceContext class with a static method which is capable of querying the context for a reference:

             

            @Inject @Reference
            private AnotherService anotherService;
            
            public void foo(String content) {
                Context context = ServiceContext.getContext(anotherService);
                context.setProperty("bleh", "meh");
                anotherService.doSomething(...);
            }
            

             

            The above is roughly the same implementation as the @Inject approach in my first post, but perhaps the presentation is a bit less funky for the user. :-)

            • 3. Re: Context injection for bean services
              tfennelly

              I was thinking along the lines of somehow registering a Context setting callback (for the service interface instance) at the time of invocation of the target service operation.  The bean client proxy would call this back with the real Context instance associated with the real Exchange instance created by the proxy during the interface invocation.  Not quite sure how that would look... need to think about it some more.  Maybe something like...

               

              public void foo(String content) {    
              
                  ServiceContext.registerSettingCallback(anotherService, new SettingCallback () {
                      public void set(Context context) {
                          context.setProperty("bleh", "meh");
                          context.setProperty("bleh", "meh");
                      }
                  });
              
                  anotherService.doSomething(...);
              }
              

               

              Yeah... thinking some more :-)

              • 4. Re: Context injection for bean services
                kcbabo

                Well, we both agree on what has to happened under the covers. :-)  The callback method seems a bit verbose to me, but that's largely a matter of personal preference.  I'm sure people will be more than happy to throw in their $0.02 on what looks best to them.