Tuesday, February 12, 2008
Posted on Tuesday, February 12, 2008 4:26:21 PM (Mountain Standard Time, UTC-07:00)  Comments [0] | 
Categories: .NET

windsor_rawlogo While it's main purpose is to provide an Inversion of Control container, and allow you to develop applications that are highly cohesive yet loosely coupled, a secondary benefit of using the Castle Windsor container is how it simplifies dealing with configuration files.

Typically if you need to have some external configuration, you'd put this into your own custom configuration section and write a class which either implemented IConfigurationSectionHandler or inherited from ConfigurationSection. If you needed to change the configuration, you'd need to change these handler classes. While this is unspeakably better than parsing .ini files, it's still pretty brittle - especially if you are being agile and refactoring your code to any great extent.

What is Castle Windsor?

It's a container that figures out how to create classes, along with all their dependencies, on the fly, from a configuration file. Somewhat like Configuration Section Handlers, but it's an awful lot more. For example...

<component id="VirtualEarthTileServiceManager"
                 type="ArcDeveloper.TileServer.Core.VirtualEarthTileServiceManager, ArcDeveloper.TileServer.Core">
        <parameters>
           <services>
            <dictionary>
              <item key="colorado">${ColoradoVETileService}</item>
              <item key="tahoe">${TahoeVETileService}</item>
            </dictionary>
          </services>
        </parameters>
      </component>

This little snippet of XML defines how the VirtualEarthTileServiceManager should be created. Basically the type is instantiated, and an IDictionary containing the keys and items it depends upon is passed into the constructor. The ${somename} notation refers to other classes in the same configuration - and they use similar syntax to have their dependencies injected at instantiation.

To actually get a VirtualEarthTileServiceManager, you just use this code...

IWindsorContainer container = new WindsorContainer(new XmlInterpreter());           
VirtualEarthTileServiceManager veTileManager = container.Resolve<VirtualEarthTileServiceManager>();

The container.Resolve call looks up the name (VirtualEarthTileServiceManager in this case) and creates the class, with all of it's dependencies.

Learning More

This post has just scratched the surface, so I recommend checking out some more information on Castle Windsor. There are quite a few articles on how Windsor works, but the best I found are a series of 4 written by Simone Busoli, and you can read them here: Part 1, Part 2, Part 3, and Part 4.

Since I'm also a fan of Scott Hanselman, give a listen to this podcast on Mock Objects, and this one on MonoRail and the Windsor container.

For more on the Virtual Earth Tile Service, see this previous post, or check out the ArcDeveloper project at Assembla.

Comments are closed.