11
Sep 06

Basic Dependency Injection (DI) for XQOM

So last night I was trying to figure out the best way of managing dependencies within code for XQOM.  My biggest requirement was no XML.  That’s funny, considering that XQOM has an XML configuration component.  So I’m not necessarily against XML configuration, though it tends to scatter the code/configuration combination.  I also don’t have a strong preference of XML vs. annotations.  I think each has its own place and I don’t really see a blurry line in the middle.  I mean, anything that you can configure using annotations, something that’s class or method dependent and without much repetition, etc…  A good example is JPA annotations, though lacking in features as compared to Hibernate, I think conceptually they are great (and Hibernate’s extensions are awesome).  I mean, it just makes perfect sense to annotate your POJO with relational persistence stuff, since each configuration (annotation) is closely tied to class/method/attribute.  XML configuration files are great for anything that’s global and/or verbose, like query mappings with iBatis SQL Maps and XQOM, global properties used by multiple classes.

In the case of XQOM, though I could have settled with XML configurations, the idea of having to edit XML each time an implementation class changes didn’t make a lot of sense to me.  The Drivers are a reification of the Separated Interface pattern and being that providers will implement the drivers in their own package namespace, yet another XML configuration file within the classpath that needs to be discovered and parsed, would quickly become a mess.  I needed something more flexible and because my object dependency and lifecycle requirements are not complex, I didn’t want to get Spring or PicoContainer into the mix, though I almost went with Pico, mostly due to its runtime code configuration capabilities.

After going back and forth about the benefits of using a IOC framework, I still couldn’t justify using it for my requirements.  Rudimentary IOC implementations that don’t require complex object lifecycle management are very simple to implement and that’s not where Spring shines per say.

The next solution was to implement the Registry pattern.  A global singleton would do the job, but the drawback of having to recompile the code each time the implementation changes, was again something I didn’t want to bother with.  Especially when we talk about Driver implementations.

So after more thought I settled with the JDBC model.  I really like it.  It’s sort of a Plugin pattern reification (PEAA), though without any static configuration files, which dynamically binds itself.  Basically, the Driver interface must implement a static code block, which upon loading, will register itself with the global singleton.  That’s basically what happens in JDBC when you execute…

Class.forName(“org.namespace.DriverImpl”);

Basically the DriverImpl class would have something like this…

package org.namespace;

public class DriverImpl implements Driver {

  static {
    DriverManager.register(new DriverImpl());
  }   

}

The DriverManager class would then look like this…

public class DriverManager {
  private volatile static Driver driverImpl;

  public static void registerDriver(Driver driver) {
    driverImpl = driver;
  }

}

I use volatile keyword, since there might be a use-case of different threads registering a different driver, and I want to ensure that it’s visible to all other threads.  I could have synchronized the registerDriver method as well, in this case, I don’t think it matters.  I try not to use synchronized in cases where data corruption is not a concern, rather the actual visibility of data.

With that implementation and a homegrown constructor based DI (CDI) or as also sometimes called “type 3 IOC”, I was able to achieve what I needed without adding any extra dependencies and overhead.  Don’t get me wrong, I think Spring is great, but again, it should be evaluated based on your requirements.  It might be the case that I will actually require it later in the project, but my current DI requirements are just too simple.

Leave a comment