Skip navigation
2012

Rob Cernich's Blog

March 2012 Previous month Next month

Recently, I started looking at integrating the SwitchYard console into the core AS7 console.  In generic terms, the goals of this effort were:

  1. The base/core should be able to be packaged as a standalone application, without modification.
  2. An extension need only contain functionality specific to one or more extensions.
  3. Creating an extended application should be as simple as packaging the base with a select set of extensions.

 

While new to GWT, this turned out to be more difficult than I had originally anticipated.  The basic problem, creating an extension/plug-in mechanism, can be solved in many ways, most of which involve the use of a generator.  Things get complicated when GWT-Platform is thrown into the mix.  Specifically, it becomes difficult to meet the first goal.

 

The complication arises out of the following GWT-P constraints:

  • The Ginjector interface must provide a getter for all presenters.
  • The Ginjector interface must be known during code generation (GWT-P proxy generators)

 

Extending the Ginjector interface is pretty trivial (interface Foo extends ...).  Specifying the new interface is also pretty trivial (override the gin.ginjector property).  The problem then boils down to making sure the base application instantiates the extended Ginjector interface.

 

Turns out, this is pretty easy to accomplish using deferred binding, double deferred binding to be exact.  Instead instantiating the Ginjector using the traditional GWT.create(MyGinjector.class) (typically in the base application's EntryPoint), a factory class is instantiated, which then instantiates the appropriate Ginjector.

 

Tying everything together, an extended application simply needs to:

  1. Define an extended Ginjector interface (e.g. ExtendedGinjector extends BaseGinjector, ExtensionGinjector...).
  2. Override the gin.ginjector property (i.e. gin.ginjector=ExtendedGinjector).
  3. Implement a GinjectorFactory that serves up an ExtendedGinjector.
  4. Tell GWT to use its ExtendedGinjectorFactory (i.e. replace-with ...)

 

This concept can be taken a step further by changing the factory into a singleton.  This allows any part of the application to access the Ginjector through the same method of indirection.  For example,

interface GinjectorSingleton {
    BaseGinjector instance();
}

 

A specific implementation might look like:

class ExtendedGinjectorSingleton implements GinjectorSingleton {
    private static final BaseGinjector instance = GWT.create(ExtendedGinjector.class);
    public BaseGinjector instance() { return instance; }
}

 

Any part of the application can then access the Ginjector using:

BaseGinjector ginjector = GWT.<GinjectorSingleton>(GinjectorSingleton.class).instance();

 

I've put together a complete, simplified example here: https://github.com/rcernich/fools-errands/tree/master/modular-mvp

A more complex example, integrating the SwitchYard console with the core AS console can be found here:  https://github.com/jboss-switchyard/console

 

Happy coding!

Filter Blog