Saturday, August 22, 2009

Improved MEF + Unity Integration Layer

In my last post about Managed Extensibility Framework and Unity DI container I proposed a solution to make both frameworks work together in tandem, which in turn lets the developer leverage all the features from them at the same time. Now, the improved version is out, and it's a part of the MEFContrib project!

Having learned from developing the previous version, I decided to reimplement the integration layer from the ground up. The API changed very little, though ;)

The "biggest" change since the initial version is that you no longer need to provide boolean parameter during component registration in Unity to say that you want the component to be available to MEF. Now, this is done automatically using Unity container extension. So, the initialization of the layer now is super easy as it requires only single line of code :) Consider this:

// Setup
var unityContainer = new UnityContainer();
var aggregateCatalog = new AggregateCatalog();

// Register catalog and types
unityContainer.RegisterCatalog(aggregateCatalog); // this call initializes the layer
unityContainer.RegisterType<IUnityOnlyComponent, UnityOnlyComponent1>();

The first call to RegisterCatalog method does the initialization - under the hoods, ComposiotionContainer is created, and a link between it and Unity is established. Pretty easy, huh ? :)

Next, all the types are public, so for example, if the standard RegisterCatalog method doesn't fit your needs, you can easily create your own using all the provided types as building blocks. The one concrete use case that comes to my mind is that the current implementation of the RegisterCatalog method does not allow you to attach any additional export providers (your own root CompositionContainer for instance) to the underlying CompositionContainer. In such a case, you can easily create separate method which accepts export providers and initializes the layer. Investigating RegisterCatalog method might be beneficial :)

One neat implication of having all types public is that you can now establish one-way synchronization, being MEF to Unity, in which Unity container knows about MEF parts and can resolve them, and Unity to MEF, in which MEF can pull Unity's components.

Finally, I've added support for closed generics, i.e. you can pull components from Unity and MEF using generics.

The usage of this layer is quite well described on MEFContrib wiki page.

kick it on