Unity/EntLib interceptors in MEF

By Augustin Šulc

In one of our applications, we use MEF for discovery of component exports. To make it more complicated, we also wanted to use Enterprise Library interceptors for advanced logging, error handling and caching (from Policy Injection Application Block) so we needed to use Unity as well. MEFContrib was a great helper for us so we were able to use (in simplified words) MEF for exports and Unity for imports. Although there were some problems it worked. With the new version of MEFContrib, things became even easier as support for interception and open generics was added to MEF.

The current MEFContrib interceptor implementation uses Castle’s Dynamic Proxy 2 or LinFu as intercepting proxies. But as we wanted to use the original EntLib interceptors that were meant for Unity, I had to add support for Unity’s InterfaceInterceptor to MEFContrib.

Unity Interceptor

To implement UnityInterceptor for MEFContrib, I suggest to download the latest source codes for MEFContrib and build it yourself as the interception and generics support have been extended since the 1.0 release.

Supposing you already have MEFContrib running, reference it in your project and then add this class to your project:

public class UnityInterceptor : IExportedValueInterceptor
{
	public object Intercept(object value)
	{
		var interfaces = value.GetType().GetInterfaces();
		var proxyInterface = interfaces.FirstOrDefault();
		var additionalInterfaces = interfaces.Skip(1).ToArray();

		var interceptor = new InterfaceInterceptor();

		CurrentInterceptionRequest request = new CurrentInterceptionRequest(interceptor, proxyInterface, value.GetType());
		InjectionPolicy[] policies = new InjectionPolicy[] { new AttributeDrivenPolicy() };
		PolicyInjectionBehavior behaviour = new PolicyInjectionBehavior(request, policies, null);

		var proxy = Microsoft.Practices.Unity.InterceptionExtension.Intercept.ThroughProxyWithAdditionalInterfaces(
			proxyInterface,
			value,
			interceptor,
			new[] { behaviour },
			additionalInterfaces);

		return proxy;
	}
}

I will send this code to the MEFContrib team so hopefully it will be integrated into MEFContrib bits.

Then, add the following code to your MEF container initialization:

var catalog = new DirectoryCatalog(System.Web.Hosting.HostingEnvironment.MapPath("~/Bin")); // create your original MEF catalog

var interceptionConfiguration = new InterceptionConfiguration()
	.AddInterceptionCriteria(new PredicateInterceptionCriteria(
		new UnityInterceptor(),
		predicate); // predicate that filters to what export components should be interceptors applied (you will probably use some metadata filtering or omit it)
var interceptingCatalog = new InterceptingCatalog(catalog, interceptionConfiguration);
//use interceptingCatalog (initialize MEF with it)

You are done – now you can use EntLib attributes, for example, [LogCallHandler] on your components and they will work as expected!

Tags: Mef, enterprise library, Unity

2 Comments

  • Olly Atkins said

    Hi, this looks very good, if I've understood it correctly. Now, would it help me to use blocks from Enterprise Library with my application, which uses MEF rather than Prism.

    I'm very happy with MEF, but have baulked at using anything from EntLib because, although abstracts calls to Unity through IServiceLocator, it relies on Unity's ability to configure parts as they are created. It's the configuration that makes EntLib powerful, but I don't really want to change things over to using Unity.

    Thanks for sharing your work,
    Olly Atkins

  • Piotr Włodek said

    Hi,

    Indeed good stuff! Please fork MefContrib repo found at mefcontrib.com, issue pull request and I will make sure this will be included in the future release of MefContrib!

    Cheers,
    Piotr

Add a Comment