Coinjema (COntext INJEction MAchine) is an experimental Dependency Injection (DI) framework that uses AspectJ to work behind the scenes. Emphasis on experimental.

What It Does

When you instantiate a Java class, Coinjema intercepts the call and supplies the object with its dependent objects before the constructor returns. It does this via aop (AspectJ) and annotations. It can also intercept getter calls to deliver just-in-time dynamic dependencies (though this is somewhat slower).

Configuration files define these dependent objects. A large variety of file types are supported, most notably groovy script files. Going through a series of possible locations for config files, Coinjema finds the appropriate script, executes it and passes the result into your new object. Coinjema caches these results so that the scripts are only executed once (per context).

Flexibility is provided via the procedure of finding the right config/script file. Dependency objects can be specifically for the Java class in question, they can be specifically for a context, and contexts can inherit from other contexts, or Dependency objects can be shared by all Java classes in a particular context (ie think singletons).

Coinjema uses AspectJ, Groovy, and Annotations from Java 5.0 to do its work.

Goals for Coinjema

  1. More powerful configuration options
  2. Simplify
  3. Streamline configuration data
  4. Self-contained Java classes

Simplifying Your Java

There are a lot of frameworks out there that we, as developers, learn to use. When writing an app, we spend a lot of time writing code that has little to do with the problem domain our app addresses. Service Locators, framework Singletons, Factories clutter our code that's really trying to be about a Pet Store (for example). Coinjema is almost without an API. This means you get automatic DI usually with minimal procedural invokations of methods on Coinjema classes. Although you will have to use some declarative annotations, your source only looks like a solution to your problem.

When you remove excess factories, service locators and static singletons and when it becomes simple again to just create new objects - even complex ones with complex dependencies - unit testing becomes much easier.

More Powerful Configuration

Using XML for configuration seems to result in gigantic files that are very hard for a human to read, that require MBs of xml support code and more coding by the developer to traverse the resulting DOM for the information of interest. Maybe worst of all is that these monstrous XML configuration files appear to be evolving into programming languages in their own right as we begin to dump therein all our dynamic/deployment-specific logic.

Coinjema can use multiple file formats out-of-the-box as its configuration language, including Groovy, normal properties files, plain text, and even serialized java objects. New formats can be easily plugged in. Thus Coinjema recognizes the legitimate desire to offload dynamic logic into an interpreted format, and yet without the pain of using XML as a programming language syntax, for which it is awful. Groovy is easier to learn for a Java programmer than an invented XML programming language, since its output is just a normal Java class or object - probably one defined by you. Which is another advantage - no more manual retreival of untyped data from DOM trees to populate your objects. Coinjema can supply your class with an precise arbitrary Java object it needs.

As you get more comfortable using Coinjema to configure and wire your objects, you'll find yourself offloading more and more deployment specific details to these configuration files. Because it is easy and because Coinjema allows you to insert configurable data into the nooks and crannies of your source code.

Defining Your Context

Coinjema was initially inspired by this article by Sony Mathew.

A Java class that is simple enough that everything it needs can be supplied in 2-3 constructor parameters is a developer's joy. One of the reasons IoC/DI is becoming so popular is that it makes it easier to write such classes. The class can specify what it needs in its constructore or setters, and an IoC container takes care of supplying it. Any class that can so clearly state its dependencies will be far easier to write and maintain than one that spends many lines of code going out and retrieving its own dependencies.

Coinjema doesn't do anything Spring or Plexus or Hivemind can't do, but it strives to make it a simpler process while at the same time providing powerful flexibility. To use Coinjema, you will have to annotate your classes and some methods, and write tiny little Groovy scripts where Coinjema can find them.

If Coinjema isn't a joy to use, then I've failed, because that's really my goal. I love the ideas behind projects like Spring and Avalon (before it died), but the implementations make me do a lot of tedious work. And sometimes it seems like you do an awful lot of work, and then you sit back and realize just how little it got you.