Convention over configuration: Structured approach
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.
Comments
Isn't some of the point of the IoC to have the control outside of the code and in configuration files that can be edited without require code to be rebuilt?
The attribute approach is interesting - ie. same approach as using something like NHibernate attributes instead of NHibernate mapping files. Again though, as with above, if I want to plug in a new component in place of an older one - wouldn't I have to goto the code and change the attribute, requiring a rebuild, etc... ?
Outside of that concern, I think tools to build the xml is the next big step. ie. similiar to what Hayden is doing with his Repository injection.
A GUI tool to edit and build configuration files for Windsor/Spring would be fantastic. It could validate the files, etc...
That is just another option I would consider. If the tool could do the reflection for the assembly and namespace, pick up the constructor values etc.. it would speed it up and make it easier to manage.
Throw in a GUI form with the tool that showed draws lines showing the dependency relationships would add even more value. When someone else comes to review the code, they can see the 'mappings' to help them understand the system better than attempting to muddle through 1000 lines of xml.
Xml is like assembly to me :)
Comment preview