Failing Early with MEF

20 Sep 2010

Several weeks back I had the pleasure of having Glenn Block over for dinner and discourse. I showed him a project I’ve been working on, and naturally our conversation centred around my use of MEF and REST. Glenn asked that I do a couple of posts on some of the MEF stuff I had done, so this is the first one.

One of the things I frequently found happening when using MEF was:

Make a few simple changes

Run the application

Get a runtime exception

Trawl through the hierarchy of exceptions, only to find that it was a simple composition problem

More often than not, I had just forgotten to add the appropriate metadata to my types. Since this is something that can be caught early, I felt compelled to do exactly that. However, I also wanted to ensure that this verification did not result in a bloated release deployment. I just wanted something to aid the developer whilst building the application.

This uses the CompositionInfo type, which is included in the Microsoft.ComponentModel.Composition.Diagnostics assembly. As an aside, I had to build my own version of this assembly for use with Silverlight since there is none provided out of the box.

The CompositionInfo class is used to dump detailed diagnostics of composition into a string. The string is then examined for any issues by searching for "[Primary Rejection]". If any error is detected, I break into the debugger so the developer can examine the composition dump. This means the workflow above is replaced with this one (same number of steps, but far less time-consuming):

Make a few simple changes

Run the application

Debugger breaks letting me know there is a composition problem

Examine compositionDetails in the debugger to get the details of the composition error

As Glenn pointed out, it may be that you want to tweak the string search according to your particular project. In my case, I want any composition problem at all to be detected ASAP and to bail out.

Notice also that this whole affair is wrapped in an #if DEBUG block. Not only does this prevent this code itself from appearing in a release build, it also prevents the Microsoft.ComponentModel.Composition.Diagnostics assembly from appearing in your release output (assuming you don’t use it elsewhere). This was particularly important for me because it’s a Silverlight app, and I wanted the download size to be as small as possible.