Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

...

This is a proposal to use Guice to implement Dependency Injection (DI) in Roller.

Requirements

This proposal introduces DI in Roller in a pretty limited way. The idea is to get a DI framework into Roller so we can start rooting out our various factories and singletons, making the code easier to test, manage and providing more extension points.

As it stands today it's only benefits are that it 1) allows a customizer to easily switch out Roller manager classes and replace them with their own implementations and 2) make it possible for RollerFactory to instantiate other Roller-dependent classes created by folks who are customizing Roller.

These requirements are met by this proposal.

...

These issues were raised and responded to during mailing list discussions of this proposal:

  • Issue raised: "I think it is most appropriate that any instance of the Roller interface should be treated
    as immutable. "
  • Response: We use constructor injection so that Roller implementations do not have to expose setters and can remain immutable.

  • Issue raised: "To truly enforce the singleton pattern we should only provide private constructors and the single instance of the class should be created statically and returned via a public static method."
  • Response: Guice can call private constructors, so we full enforce the singleton model.

  • Issue raised: "I hope we won't be asking users to modify distributed code in order, for example, to add plugins or to swap a rendering model implementation."
  • Response: We won't require that. If you want to extend Roller's back-end you simply provide your own module class that injects the classes you want. You'll have to override one property in your roller-custom.properties file, but you will not have to touch a line of Roller code.

  • Issue raised: "From my perspective Spring is more mature, well-documented and tested, has a more open contribution model, and is in wider use amongst a broader community. Plus we have at least two committers that are using it in other settings."
  • Responses
    • Guice documentation is excellent and Guice is "simple and easy. It took me no time at all to figure out – no books or extra docs necessary."
    • "Guice now powers Google Adwords. You'd be hard pressed to find a more massively distributed, scalable, etc. Java app out there. So, I'm not particularly worried about Guice maturity and testing."
    • "Spring does not accept external committers and has no plans to do so," that's hardly an open contribution model.
    "I hope we won't be asking users to modify distributed code in order, for example, to add plugins or to swap a rendering
    • model
    implementation
    • .
    "
    • We won't require that. If you want to extend Roller's back-end you simply provide your own module class that injects the classes you want.

Design

List and describe new manager methods, Struts actions, JSP pages, macros, etc.

Changes to

...

Roller Weblogger bootstrapping

To select a back-end implementation, you set the property 'guice.backend.module' in the Roller configuration file the the class name of a Guice module that specifies the Roller interfaces. The RollerFactory will instantiate that Guice module and will use it to create and inject the Roller implementation specified by that module.

Changes to the Roller implementation and managers

Roller implementation and all manager implementations use constructor injection. The are all declared as singletons.

The DatabaseProvider class has been moved into the Core component so that it can be shared by both Weblogger and Planet. It's an abstract class and implementations are expected to provide a constructor that calls it's init method.

The Roller version of the database provider uses RollerConfig to configure the database.

Changes to Roller Planet bootstrapping

Roller Planet uses the very same setup as Roller Weblogger. As you'd expect there is a PlanetFactory and a PlanetModule. There's a PlanetDatabaseProvider that uses PlanetConfig to get database properties, etc, which uses a PlanetModule to initialize Guice and create injected instances.

Planet implementation and all manager implementations use constructor injection. The are all declared as singletons.

Changes to Roller Weblogger's Planet integration

The PlanetFactory uses the Guice back-end specified in the planet.properties file. In To use Planet in Roller we need simply provide a special different PlanetModule, one with a Planet implementation that can read reads database parameters from the Roller properties file instead of the Planet one.

This is accomplished by a special Planet persistence strategy that uses RollerConfig called and is named HibernateRollerPlanetPersistenceStrategy.java. And we 'll need have a PlanetModule that specifies that strategy, which we call RollerPlanetModule.java.

Status

This proposal is implemented in the roller_guice branch and as of June 21, 2007 is completely in-sync with the code in the Roller trunk. It's ready to merge.

Guice DI is implemented in both Weblogger and Planet and for both the Hibernate and JPA implementations and passing 100% of tests. Both Weblogger and Planet apps start, run and pass sanity testing.

Comments

Please comment on the Roller dev list.