3 Replies Latest reply on Sep 26, 2007 6:19 AM by alesj

    Microcontainer + Guice

    alesj

      Another quick thing I hacked up - this time during vacation (yup, I know, I suck at 100% relaxing) and finalized while waiting for jbossas trunk to be Mavenized.

      What you can do now is these three approaches of MC + Guice integration:
      1) programmatically

       Injector injector = Guice.createInjector(new AbstractModule()
       {
       protected void configure()
       {
       bind(Controller.class).toInstance(controller);
       bind(Singleton.class).toProvider(GuiceIntegration.fromMicrocontainer(Singleton.class, "singleton"));
       bind(Prototype.class).toProvider(GuiceIntegration.fromMicrocontainer(Prototype.class, "prototype"));
       }
       });
      

      2) through metadata
       AbstractBeanMetaData injectorBean = new AbstractBeanMetaData("injector", GuiceInjectorFactory.class.getName());
       AbstractConstructorMetaData constructor = new AbstractConstructorMetaData();
       constructor.setFactoryClass(GuiceInjectorFactory.class.getName());
       constructor.setFactoryMethod("createInjector");
       List<ParameterMetaData> parameters = new ArrayList<ParameterMetaData>();
       parameters.add(new AbstractParameterMetaData(new AbstractDependencyValueMetaData(KernelConstants.KERNEL_NAME)));
       AbstractArrayMetaData array = new AbstractArrayMetaData();
       array.add(new AbstractValueMetaData(GuiceObject.ALL));
       parameters.add(new AbstractParameterMetaData(array));
       constructor.setParameters(parameters);
       injectorBean.setConstructor(constructor);
       controller.install(injectorBean);
      
       ControllerContext injectorContext = controller.getInstalledContext("injector");
       assertNotNull(injectorContext);
       Injector injector = (Injector)injectorContext.getTarget();
      

      3) XML
      <bean name="injector" class="org.jboss.guice.plugins.GuiceInjectorFactory">
       <constructor factoryClass="org.jboss.guice.plugins.GuiceInjectorFactory" factoryMethod="createInjector">
       <parameter>jboss.kernel:service=Kernel</parameter>
       <parameter>
       <array>
       <bean name="BindAll" class="org.jboss.guice.plugins.AllGuiceObject">
       <constructor factoryClass="org.jboss.guice.plugins.AllGuiceObject" factoryMethod="getInstance"/>
       </bean>
       </array>
       </parameter>
       </constructor>
      </bean>
      


      Or check out GuiceTestSuite. ;-)

      I've commited the code --> adding new guice-int module.
      Will add some docs asap.

      OK, back to ProfileService ...

        • 1. Re: Microcontainer + Guice
          bill.burke

          Blog about this in detail please.

          • 2. Re: Microcontainer + Guice
            bill.burke

            Great stuff...Always good to see somebody to take time away from the grind to innovate :)

            • 3. Re: Microcontainer + Guice
              alesj

              I've also added a way to do injection the other way around: from Guice into MC.

               AbstractBeanMetaData guicePlugin = new AbstractBeanMetaData("GuicePlugin", GuiceKernelRegistryEntryPlugin.class.getName());
               AbstractConstructorMetaData constructor = new AbstractConstructorMetaData();
               AbstractArrayMetaData arrayMetaData = new AbstractArrayMetaData();
               final Singleton singleton = new Singleton();
               Module module = new AbstractModule()
               {
               protected void configure()
               {
               bind(Singleton.class).toInstance(singleton);
               }
               };
               arrayMetaData.add(new AbstractValueMetaData(module));
               constructor.setParameters(Collections.singletonList((ParameterMetaData)new AbstractParameterMetaData(arrayMetaData)));
               guicePlugin.setConstructor(constructor);
               controller.install(guicePlugin);
              
               BeanMetaData holderBean = new AbstractBeanMetaData("holder", SingletonHolder.class.getName());
               controller.install(holderBean);
              
               ControllerContext holderContext = controller.getInstalledContext("holder");
               assertNotNull(holderContext);
               SingletonHolder holder = (SingletonHolder)holderContext.getTarget();
               assertNotNull(holder);
               assertEquals(singleton, holder.getSingleton());
              
              


              The detail is in GuiceKernelRegistryEntryPlugin, which acts as a middle man between MC registry and Guice Injector instance.

              public class GuiceKernelRegistryEntryPlugin implements KernelRegistryPlugin
              {
               private Injector injector;
              
               public GuiceKernelRegistryEntryPlugin(Module... modules)
               {
               injector = Guice.createInjector(modules);
               }
              
               public void destroy()
               {
               injector = null;
               }
              
               public KernelRegistryEntry getEntry(Object name)
               {
               KernelRegistryEntry entry = null;
               try
               {
               if (name instanceof Class<?>)
               {
               Class<?> clazz = (Class<?>)name;
               entry = new AbstractKernelRegistryEntry(name, injector.getInstance(clazz));
               }
               else if (name instanceof Key)
               {
               Key<?> key = (Key<?>)name;
               entry = new AbstractKernelRegistryEntry(name, injector.getInstance(key));
               }
               }
               catch (Exception ignored)
               {
               }
               return entry;
               }
              }
              


              MC documentation has already been updated with this new Guice-int module.