Prism 4, MEF and the CompositionInitializer

So I have been using MEF (Managed Extensibility Framework) for a while now on most of my WPF projects. Lately, I have been really getting a lot of use out of Prism 4.0 as well and utilizing the built in MEF with the MefBootstrapper.

One of the things that I always found a bit troublesome however was what to do when you need a non-exported class to satisfy its imports from MEF. This came up on a recent project, as I was using the IEventAggregator from Prism, thought it would be useful to have it in classes that may not come from MEF- i.e. classes that are new’ed up depending on the business logic dictated. Now, the true MEF heads may say, ‘Nooooo! That’s not what MEF is for!’. But I thought I would see how it worked anyway.

To solve this, one approach was to pass in my IEventAggregator to my class through the constructor, but this didn’t seem too elegant. What if I need other imports besides the IEventAggregator? Then potentially I need to pass in more and more stuff to the constructor.

What I really needed, was some way to tell the class that it has imports it needs to satisfy, and notify that class that it needs to check the already existing container for this. This is where the CompositionInitializer comes in. One problem with that is that the CompositionInitializer was designed for Silverlight, and my application is MEF. But, no worries, Glenn Block had anticipated my need and kindly written a WPF CompositionInitializer, to be found here. Thanks Glenn. And in addition, I found lots of other great info from Reed Copsey’s site. Thanks Reed.

So I placed my CompositionInitializer in my non-exported class in the constructor:

// No export here
public class MyClass
{
	public MyClass()
	{
		CompositionInitializer.SatisfyImports( this );
	}

	[Import]
	private IEventAggregator EventAggregator { get; set; }
}

But when I ran the code, even though I had a valid import for my IEventAggregator, none of my messages were being received. A bit of googling brought me here. Aha! Simply placing my CompositionInitializer.SatisfyImports( this ) in the constructor is insufficient. How, after all, does the CompositionInitializer know what container you are using? I was so used to MEF magic that it hadn’t occurred to me that CompositionInitializer needs to have its container set.

By adding the following line to my BootStrapper file in a location that gets called after CreateShell():

CompositionHost.Initialize( Container );

My CompositionInitializer was now armed with the appropriate container, and everything worked great in the constructor. Now I was able to new up an instance of any class and satisfy its imports against my Container.