A couple of weekends ago, we had a design meeting on the WPF project I mentioned a week or two ago, which now glories in the codename Clock Tower 7 (don’t ask!).
Brian and Ian will have plenty to add, but here’s my perspective…
Coffee and extensibility
Once we’d decided which brand of coffee was going to fuel the day, thoughts turned to the extensibility model.
First question: do we need an extensibility model?
Well, that’s probably another blog post ; premature extensibility is like premature optimization – tempting, so very tempting. Suffice to say (for now) that we do want to allow ourselves - and 3rd parties - to develop additional data providers for the application, and bind those at runtime.
Choices…so many choices…
We considered three basic options for the plug-in framework.
1) Roll our own
2) Managed AddIn Framework (MAF)
3) Managed Extensibility Framework (MEF)
We pretty quickly rejected “roll our own”. A plug-in framework is hard to get right, not least in terms of the programming model, security considerations and testability. So why shouldn’t we try to get the “Goldilocks” implementation – not too hot, not too cold, but just right for our app?
Well, groups inside Microsoft have had several goes at this with .NET, with varying degrees of success and compromise. On top of that there are innumerable 3rd party efforts (try querying “.NET Plugin architecture” in your favourite search engine).
Adding to this menagerie just didn’t seem to be made of win.
Next under consideration was MAF. This was added in .NET 3.5, and provides very sophisticated plug in capabilities. It even has the option of full AppDomain isolation for security, stability, and the ability to unload code – almost the holy grail of plug-in models.
It even goes some way to supporting WPF add ins. However, it turns out that WPF is not happy at all in the presence of multiple AppDomains. It might seem to work, but it isn’t really supported. And while MAF is very powerful, and an in-the-box component of the .NET framework, it is also quite complex to use. Much of this complexity serves the goal of AppDomain isolation, and if we’re ditching that for WPF, then it is pain we could happily do without.
The third option is MEF. This is a new .NET library that enables in-AppDomain runtime extensibility, with a simple programming model that is itself extensible.
At the present time, MEF is not an in-the-box component of the .NET framework, but the published intention is that it will be, in the .NET 4.0 timeframe. At the moment we can download full source and binaries from the Codeplex site linked above. (They’ve just shipped “preview 5”.)
The major downside to MEF is that the programming model is still changing with each preview, so it is some way from being a totally stable target. That said, migration between versions has been pretty painless so far.
The other limitation of MEF is that we don’t have the potential isolation and unloading benefits of AppDomain separation. This was a serious consideration for us – not just from the security perspective, but also for crash isolation; we’d like to do as much as possible to prevent a 3rd party plug in from bringing down our application. In managed code, this is much less likely to happen “by accident”, and we can catch most cases. Defending ourselves against a malicious plug-in is a topic for another day.
On balance, we think that the programming model and future-proofing makes MEF the compelling choice for our application.