Convention over configuration: Structured approach

time to read 3 min | 494 words

Hammett has a post that made me think. He is talking about configuring Spring for Java and has this to comment:

I can’t understand this uncontrolled passion that java programmers carry for xml.

I can certainly agree with him about that, but I got to the same point a long time ago with Windsor. I had an application which was rife with components. I am talking about many dozens of generic (as in MyComponent<T>) components, all of which required registration in the config file, which got to be fairly annoying very fast.

I solved that by creating Binsor, a Boo DSL for configuring an IoC container. Initially, it was very similar to the Batch Registration Facility, but I pushed it much further, until today I do all my Windsor configuration using Windsor.boo, and its existence is a core part of my application architecture. Why? Because I can do things like this:

controllersAssemblies = (Assembly.Load("MyApp.Web"), Assembly.Load("Castle.MonoRail.ViewComponents") )
for asm in controllersAssemblies:
	for type in asm.GetTypes():
		continue if type.Name == "ScheduledTasksController"
		if typeof(Controller).IsAssignableFrom(type):
			IoC.Container.AddComponent(type.FullName, type)
		if not typeof(ViewComponent).IsAssignableFrom(type):
			IoC.Container.AddComponent(type.Name, type)

The immediate result of this type of behavior is that I don't have any weight of the IoC, I just develop as I would normally would, and it catches up with everything that it needs to handle.

I recently had the chance to maintain a MonoRail application that used XML for configuring Windsor, and by the third time that I added a controller, I was pretty annoyed. Each and every time, I had an additional step to perform before I could run the code. Compared to the approach that I was using, it was hardly zero friction.

Of course, my approach is not flawless in any mean, there is a bug in the configuration above, can you spot it?

The point of this post, which I have been trying to get to for a while, while random electrical pulses moved my fingers in interesting ways, is that I have began not only to use this to a great extent (all projects in the last year or so are based on this idea), but I have started to actually design with this in mind.

The end result right now is that I am relying a lot more on commands patterns and attributes for selections. This means that I often do things like:

[SelectionCriteria(Selection.FirstOption, Selection.SecondOption)]
public void SomeSpecficCommand : Command<ObjectActingUpon>
{
	public override void Execute()
	{
	}
}

You can see a more real world sample here, but the idea is to declaratively express the intent, have the configuration figure out what I want, and make it happen. The nice thing, most of the time, It Just Works. And the nice thing about utilizing Binsor is that I can adapt the convention very easily. So I can have many nice conventions, each for a particular situation.