Welcome to EMC Consulting Blogs Sign in | Join | Help

Howard van Rooijen's EMC Consulting Blog (2004 - 2010)

This blog has now moved to http://howard.vanrooijen.co.uk/blog - please update your subscriptions if you wish to receive new content.

Using MEF and Castle Windsor to improve decoupling in your architecture

For the last 6 months I’ve been leading a small team to deliver a “best of breed” ecommerce retail site, based on ASP.NET MVC, Sharp Architecture, NHibernate, Fluent NHibernate, Spark View Engine, N2CMS, Castle Windsor, xVal Framework, AutoMapper, PostSharp, Gallio / MBUnit / DevelopWithPassion.bdd, Solr and SolrNet. We delivered it in 10 x 2 week sprints and went live in time for the Halloween peak trading period. You may have been following blog posts by James Broome and Jonathan George who have been covering some of the different aspects of the solution, from BDD to Performance Testing and Optimisation. I’ve collated these posts (and some of my own on the project) into a delicious list: http://delicious.com/howardvanrooijen/fdo-casestudy for those who may be interested.

You can now see the site for yourself at http://www.fancydressoutfitters.co.uk

As I’ve mentioned the fundamental architecture of the site is based on Sharp Architecture – an amazing Open Source Project which the aims to pull together best practices around MVC / NHibernate / Castle etc. It really is an awesome framework and I attribute a lot of the success of the project to this. We extended the core framework – contributing many of the changes back to the project (multiple db support, XVal validation support, etc). One of our main project practices was doing a weekly code review – using NDepend to give us a good view of the project and the cohesiveness of the overall architecture (we were running fast). When I was trying to familiarise myself with #Arch - I spent some time looking at the “Northwind” reference project. I used NDepend to take a look at the dependencies and it left a little bit of a bad taste in my mouth:

northwind-dependencies

I wrote a post to the group - the general theme was that we thought there were too many dependencies across the different layers and that if the project was supposed to encompass a “best practice reference architecture” it wasn’t as loosely coupled as it should be – and this was mainly due to NHibernate initialisation requirements. No-one really agreed with me (mainly because of the law of diminishing returns and the effort required to implement). But still the problem irked me and I started pondering possible ways of improving the architecture to remove this coupling.

I had the idea of implementing a “Registrar” pattern that would be responsible for orchestrating type registration with the container and then maybe extending that with a “Bootstrapper” pattern that would be responsible for initialisation. I also wanted a convention over configuration approach that would mean that as long as developers follow the convention – they don’t need to get involved in any of the plumbing. The main problem is that Castle Windsor doesn’t really have a mechanism for dynamic type discovery and there is a fundamental issue with loading types dynamically, in that if the assembly is a project reference, but does not have a hard coded reference in a project – that assembly is not loaded into the AppDomain, thus not dynamically discoverable at runtime.

At this point I realised that MEF might have an answer. Implementing this in MEF is trivially simple and only uses some of its basic features – but that’s exactly why MEF is so useful!

Here are the steps for implementation:

First create a marker interface that you can use to define which assembly you want to load to you are registering doing auto registering of types with Castle:

public interface IComponentRegistrarMarker { }

For each project add a marker in the properties folder:

public class InfrastructureRegistrarMarker : IComponentRegistrarMarker {}

Next, define an interface that you are going to use to register your components across the different project – this should ideally like in a *.Framework, *.Utilities or *.Core type of project, that is referenced by all projects:

public interface IComponentRegistrar
{
   void Register(IWindsorContainer container);
}

Next, create a concrete implementation of the above interface so that you can register dependant components using Castle Windsor’s Auto Registration feature. Now use the MEF Export attribute to state that the implementation exports the IComponentRegistrar type. The use of MEF is quite a simple, yet powerful solution as it allows each assembly to auto register its own dependencies:

[Export(typeof(IComponentRegistrar))]
public class InfrastructureComonentRegistraronentRegistrar : IComponentRegistrar
{
   public void Register(IWindsorContainer container)
   {
      container.Register(
       AllTypes.Pick()
        .FromAssembly(Assembly.GetAssembly(typeof(InfrastructureRegistrarMarker))) 
        .WithService.FirstNonGenericCoreInterface("MefAndWindsor.Domain"));
   }
}

Now here is where MEF comes into its own and delivers something over the shortcomings of both the generic .NET Framework and Castle; use MEF to inspect the current folder (i.e. bin\debug) and load only MefAndWindsor Types. Then retrieve every type that is marked an “export” of the IComponentRegistrar interface, then use some Lambda syntax to call it’s Register method passing in the container:

public static class RegistrarOrchestrator
{
   public static void Register(IWindsorContainer container, string path)
   {
      var compositionContainer = new CompositionContainer(new DirectoryCatalog(path, "MefAndWindsor.*.dll"));
      compositionContainer
        .GetExports<IComponentRegistrar>()
        .Each(e => e.Value.Register(container));
   }
}

And there you go – configuring your application to use a container is reduced to 3 lines of code:

var container = new WindsorContainer();
ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
RegistrarOrchestrator.Register(container);

I didn’t have time to refactor the Nothwinds sample app – so the comparison isn’t like for like, but you should get the idea. The result is that the app is more loosely coupled – now the *.Console app really doesn’t have a dependency on the *.Infrastructure assembly:

mefandwindsor-dependencies

You would still need to reference the *.Infrastructure project in the *.Console project to ensure that the assembly is copied into the bin folder. To totally decouple the solution you could achieve the same affect with a Post Build Step or custom MSBuild target:

This pattern could be extended – for example a IComponentInitialiser could be used to initialise dependant frameworks, such as NHibernate – this would allow you to have total persistence ignorance in your architecture.

If you are interested in seeing the code – I’ve uploaded the demo to my CodePlex Project.

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Krzysztof Koźmic said:

Howard,

Cool approach indeed. However, you don't need IComponentRegistrar.

Windsor already has IWindsorInstaller targetted at this scenario.

you then do windsorContainer.Install(paramsArrayOfYourCustomInstallers);

and you're done.

you can see my take at this (from half year ago) here: http://kozmic.pl/archive/0001/01/01/meffing-with-castle-windsor.aspx

November 13, 2009 8:46 AM

Leave a Comment

(required) 
(optional)
(required) 
Submit

This Blog

Syndication

News

This blog has now moved - please visit http://howard.vanrooijen.co.uk/blog for new content!
Add to Live.com
Powered by Community Server (Personal Edition), by Telligent Systems