Given the momentum behind MEF at Microsoft and the fact that MEF has shipped in the box with Silverlight 4, you may find it somewhat disappointing that MEF is not available for Windows Phone 7. Due to low level differences in the CLR for Windows Phone 7, you can’t just grab MEF from Codeplex either – read on to see the solution.
{Edit: I later posted the binaries http://www.damonpayne.com/post/2011/03/01/MEF-for-Windows-Phone-7.aspx }
The Goal
Given the Marketplace restrictions, we know that our application code must go through a QA process and be signed in order to be deployable to the Windows Phone 7 (henceforth The Phone, or WP7). It’s not surprising then that the popular Silverlight Dynamic Recomposition techniques using MEF and downloaded XAP files won’t work. However, it’s still incredibly useful to be able to use DeploymentCatalog and friends to wire together components in an application. Getting this scenario working on The Phone is how I’m defining success for now.
Getting MEF to Build and Run
Prior to .NET 4 and Silverlight 4 shipping MEF has been available in preview form on Codeplex. I was surprised that, being a daily reader of Silverlightshow.net, I hadn’t already seen an article submitted by someone who had built MEF for Windows Phone 7. Now I know why.
Trial 1 – Building MEF Preview 9 as a Silverlight 3 Project
Many Silverlight 3 assemblies will turn out to just work on The Phone. It seems reasonable that the first thing to try is to get MEF Preview 9 from CodePlex. You can build this as a Silverlight 3 project and then reference the binary output from a WP7 project. Trying to use DeploymentCatalog immediately blows up at runtime though. That would have been too easy.
Trial 2 – Referencing MEF Preview 9 as a Silverlight 3 Project with Source
Rather than just building and referencing System.ComponentModel.Composition and System.ComponentModel.Composition.Initialization as assemblies, I thought I’d add the source projects to my test solution and step through to see what was going on. It could always be something simple and obvious. I was getting some interesting MissingMethodException and MethodAccessException behavior so as feared this was likely going to involve source code modifications to get it working, if it was possible at all. I moved on to the next logical choice.
Trial 3 – Building MEF as Windows Phone 7 Class Libraries
At this point I assumed some low-level binary incompatibility or missing Type was the issue so I decided to create two new WPF class library projects and add the respective MEF source files to these. Building MEF using Windows Phone 7 Class Library as the project type would immediately show me any issues with base class library parity. At this point I was confronted by three major issues I was previously unaware of.
No System.Reflection.Emit
I was always extremely happy that SRE was included in Silverlight, so I was a bit surprised to find it missing from The Phone. Sure, we never had it in Compact Framework development but The Phone is a much more heterogeneous platform compared to the giant universe of Windows CE/Windows Mobile hardware. This spells doom for some of my more advanced Silverlight development scenarios, and for certain MEF features as well. MEF uses SRE to create dynamic implementations of interfaces for Metadata – very handy for Lazy Imports.
I have a reasonably easy workaround for the Import Metadata issue, but eager to get my main success scenario working I commented this feature out for now and moved on.
No IQueryable
The MEF code uses a fair bit of IQueryable internally. Not being familiar enough with LINQ Expression hacking I can’t fathom why this was left out. Performance implications? Required Reflection Emit? I don’t know. Nonetheless, this code had to be changed in places like TypeCatalog, AggregateCatalog, and the ComposablePartCatalog base class. Until I at least got this to compile I wouldn’t know if IEnumerable would work as a surrogate for IQueryable or not.
{No IQueryable http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/79858a29-4db0-460d-9a75-3630211a28fb/ }
No Dynamic Assembly Loading. Period.
Silverlight XAP files are packaged with a Deployment Manifest that makes it easy to enumerate the assemblies included in a given XAP file. In the Full versions of Silverlight you can use these AssemblyParts to load the assemblies and do useful things like add them to an AssemblyCatalog for MEF.
In their Zeal to prevent you from somehow loading code onto The Phone that had not gone through The Marketplace, you can’t load assemblies by name using this technique or any other technique. Unfortunately this even includes assemblies that are hard-referenced by your WP7 Application. What the harm would be in allowing developers to get a handle to all the assemblies that are hard-referenced is beyond me but this one is a showstopper. Or is it?
We Can Continue, but Should We?
Suppose we can keep going. Is MEF worthless in the Windows Phone 7 scenario given these limitations or is there still value to be had? MEF is about Composition, Isolation, Separation, and Extensibility. MEF is about programming against abstractions and making it easy for third parties who are unknown at compile time to extend your applications. While some of these benefits cannot be realized given the WP7 limitations there are still meaningful benefits.
- Suppose you are developing frameworks and using MEF as your mechanism of wiring up Abstractions to their Implementations. If you want to share any code with The Phone, it would suck to not at least be able to use MEF to map “IWidget to DefaultWidget”. Programming against abstractions is always good.
- You may simply prefer the Import/Export programming model to alternatives like Factories and Service Locators. Doing these things manually can take a lot of code.
- You may be used to ImportMany semantics, which is not a common feature in IoC containers that I know of.
- Microsoft may loosen up the WP7 deployment story in the future and you want to be ready.
- You love MEF and you have a Man-crush on Glenn Block and you want to achieve Universal MEFness
The Current Workaround
For my part, I am working on frameworks that I’d like to recompile for Windows Phone 7, and I’ve become very accustomed to the great programming model MEF enables. I’m NOT going to manually register every single Type I use to get around the DeploymentCatalog issues though. Given that we can’t load assemblies by name, is there any compromise we can make? Yes there is.
Since we can only hard-reference assemblies for Windows Phone applications, we can cheat and get a handle to each assembly we want to participate in Composition by using any Type from each assembly. By then modifying DeploymentCatalog to add an additional constructor we can at least run some sample code and see what’s working and what’s not. I went ahead and created a Mobile version of the Metro BBQ example I’ve been using lately. I have an entry point application and two module assemblies and I’d like to to use MEF to glue them all together.

In the entry point application there is a simple UI that displays Gas Grills and Charcoal Grills, and I’d like to create a simple ViewModel that gets populated with IGrill implementations via MEF Catalogs.
namespace MetroBBQ.Mobile
{
public class ShellViewModel : INotifyPropertyChanged
{
private IEnumerable<IGrill> _AllGrills;
[ImportMany]
public IEnumerable<IGrill> AllGrills
{
get { return _AllGrills; }
set
{
_AllGrills = value;
OnPropertyChanged("AllGrills");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propName)
{
if (null != PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
}
Now using some bootstrapper types from each assembly along with my DeploymentCatalog modifications, I create a CompositionContainer, and give it all a try.
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
var shimTypes = new List<Type> { typeof(MetroBBQ.Mobile.GasGrills.Bootstrapper), typeof(MetroBBQ.Mobile.CharcoalGrills.Bootstrapper), GetType() } ;
var deploymentCatalog = new DeploymentCatalog(shimTypes);
var container = new CompositionContainer(deploymentCatalog);
var vm = new ShellViewModel();
container.ComposeParts(vm);
DataContext = vm;
}
Sure enough, I’m now able to Compose Parts just like my MEF experience on other platforms. There are a LOT of other scenarios to test but I’m encouraged by this initial success. My ViewModel gets populated with IGrill implementations from two other assemblies in my Windows Phone 7 application.
What do you think, dear reader? Is it worth doing more testing or shall I add this to the collection of forgotten novelties on my shelf? Would you like the source code? Is this worthy of MEFContrib? Leave me a comment! For my part, I’m happy to be able to continue my MEF experience on this new platform.