Poor Man's Dependency Injection
Dependency Injection is applied polymorphism. Parts of the application are developed against interfaces or abstract classes without the need to know their actual implementation. In unit testing, for example, dependency injection has become a common technique to simulate the production environment for the classes under test by so-called mock objects.When talking about DI, most developers think of more or less extensive frameworks that provide dependency configuration at runtime. However, in a lot of cases DI is perfectly sufficient at build- or compile-time. For thoses cases, the wurbelizer may be an ultra lightweight alternative.
Injecting the Code
Basically, dependency injection boils down to varying class names. In Java, for example, this can be achieved at runtime via the class loader:Class.forName(className).newInstance()However, at compile time, there is no concept for varying code at all. Even with generics, if T is a type variable, you cannot write new T() because of type erasure. This is where the wurbelizer comes in. It allows the declaration of type variables at build-time!
First, we need to declare the "variables". A good place for that is the project's ant-file:
Switching between the mock objects and the production classes is now easily done by changing the ant-property $plc in the build file.
Next, we must tell the wurbelizer where to inject the actual class names. A simple Inject-wurblet with a so-called unnamed wurblet anchor does the trick:
In this example, the text between the two empty block comments /**/ has been replaced by the contents of the variable $plcConnection. And that's it!
Notes
- Although with wurblets you don't need factory classes to instantiate the objects being injected, it is still recommended to use factories. The factory has just been dropped to make this example as short as possible.
- Compared to DI frameworks, the wurblet approach has the advantage that there is no extra runtime cost. All the dependencies are resolved at compile time.
- The next Java 7 will probably provide reifiable generics which will allow things like new T().
