Tuesday, March 29, 2011

Integrating Castle Windsor with MEF

Some time ago I developed a small chunk of code which enabled Unity and Managed Extensibility Framework to consume each others components (see my posts here and here). After a while I hooked up with @TheCodeJunkie who was, and still is, responsible for managing MefContrib project, which aims at delivering high quality MEF extensions developed by the community. Soon, my integration layer became a part of that library! Yeah, I was excited =) After a while, I posted a refined version. Basically, I extracted some generic code from the existing Unity integration stuff which could be reused with other DI containers. So in this post I want to discuss a simple adapter for Castle Windsor which is built using that infrastructure and enables MEF to consume components registered in Windsor container.

Implementation

All the required stuff lives in MefContrib.Containers namespace (MefContrib.dll assembly) which has been renamed from MefContrib.Integration as the new name is more meaningful. There is one interface and one ExportProvider which are interesting in this scenario. IContainerAdapter is an interface which encapsulates basic behaviour of a typical IoC container. The ContainerExportProvider class then uses that interface to extract relevant components from the IoC and provides them to MEF. So the only part missing from the equation is the actual IContainerAdapter implementation for Windsor Container. Unsurprisingly, it is very simple. Here it comes:

public class WindsorContainerAdapter : ContainerAdapterBase
{
private readonly WindsorContainer _container;

public WindsorContainerAdapter(WindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}

_container = container;
_container.Kernel.ComponentRegistered += ComponentRegisteredHandler;
}

private void ComponentRegisteredHandler(string key, IHandler handler)
{
RegisterCastleComponent(handler);
}

public override object Resolve(Type type, string name)
{
return name == null
? _container.Resolve(type)
: _container.Resolve(name, type);
}

public override void Initialize()
{
var handlers = _container.Kernel.GetAssignableHandlers(typeof (object));
foreach (var handler in handlers)
{
RegisterCastleComponent(handler);
}
}

private void RegisterCastleComponent(IHandler handler)
{
var name = handler.ComponentModel.Name;
var type = handler.Service;

// By default, Windsor assigns implementation's full name for the key,
// but for a default key we want to pass null instead
if (handler.ComponentModel.Implementation.FullName == name)
{
name = null;
}

OnRegisteringComponent(type, name);
}
}


All we have to do is to inform ContainerAdapterBase that a component has been registered within the container so that the ContainerExportProvider knows which types are available. In the Initialize method we have a chance to register components which were registered in the IoC container before the adapter had a chance to intercept this information itself. The Resolve method will be called by MEF in order to get a component from IoC.

Usage

The usage is pretty straightforward. Let’s assume we have IFoo service which maps to Foo implementation. Here’s the code which registers these types within Castle Windsor and then IFoo is consumed by MEF.

var windsorContainer = new WindsorContainer();
var provider = new ContainerExportProvider(new WindsorContainerAdapter(windsorContainer));
var compositionContainer = new CompositionContainer(provider);

// Setup Castle Windsor
windsorContainer.Register(Component.For<IFoo>().ImplementedBy<Foo>());

var fooExport = compositionContainer.GetExport<IFoo>();

Of course, named registration is supported. Also MEF can resolve all IFoo implementations if it happens that IFoo is mapped to more than one implementation (thanks to named registration). See all the tests available in the provided solution. 

Where can I find this ?

This code with some NUnit tests is available as a sample for the MefContrib project. You can find its sources at https://github.com/MefContrib/MefContrib-Samples.

Enjoy!

Tuesday, March 22, 2011

Geeks On Tour – Me speaking about MEF/MefContrib / Extensibility

3rd-Geeks-on-Tour logo

I’m happy to announce that between April 18th and 20th 2011 I will be speaking on Geeks on Tour roadshow! Three days, three cities – Katowice, Wrocław, Poznań, two presentations each day. Wondering what MEF is ? How does it relate to IoC and Managed Addin Framework ? When to choose which ? What’s MefContrib and how it can help you ? How to write your custom MEF extensions ? Join me on the talks to find out this and many more! You can find more details about the event, including detailed agenda, on geeksontour.pl official page!

I will be covering all the aspects regarding MEF, its strong and week sides, how does MEF relate to other technologies. I will be showing some of the cool features MEF team is preparing as part of MEF 2 release. I will show some cool features which are part of MefContrib project. Finally, I will deep dive into MEF internals, I will show how to write custom exporters and catalogs. The presentations will be held in Polish. Entrance is free :) See you there!

Presentation and full source code is available below.