MEF and .NET Standard
I’ve been working on a new side project recently which has really got me excited again! There’s not too much to tell about it just yet, but one of its aims is to create a highly configurable and modular way of creating screening workflows.
As a part of this side project, I needed to create an architecture that could be extended, both by us internally, and by our customers externally.
Since my colleague had just done some training for our graduate scheme on the Managed Extensibility Framework (MEF), I thought I’d take a look at it too, to see if it could offer a solution. While the graduate course focused on MEF in the .NET Framework, I’m always keen to push as much of my architecture into the cross platform realms of .NET Core and .NET Standard, so naturally, I headed in that direction.
Unfortunately it seems that while MEF is included in the .NET Standard APIs, it’s doesn’t have much documentation. Instead, I pulled together blog posts about MEF in .NET Core and .NET Framework and started writing some code.gist
Trying it out
First, I started creating my projects. I created my app project as a WPF desktop app. My plugins and common library projects targeted the .NET Standard.
Next was implementing MEF, which turns out to be incredibly easy. I already had an interface that I wanted to expose via plugins (INodeDefinition), so there were only a few things I needed to do:
- Export my interface in my plugins
- Load assemblies I want to search
- Use MEF to create new instances of my exported interfaces
Exporting the interface was straight forward. I created a class that derives from the interface (my concrete plugin) and decorated it with an Export attribute.
Loading the assemblies in the consuming application is next. Doing so requires just a few lines of file enumeration and assembly loading.
Finally, we use MEF to create instances of the concrete classes we exported, cast as our interface.
Here we can see we’re using a ConventionBuilder and ContainerConfiguration. The ConventionBuilder allows us to provides rules for how to export our classes. The ContainerConfiguration allows us to retrieve new instances of them, based on our conventions and assemblies.
So not much to it. The really neat thing is that since my common and plugin libraries are both .NET Standard, they are also cross platform. This means they’ll work with my WPF app in Windows and any future .NET Core app on Mac or Linux (or in the cloud!). Neat!
As this project continues, I may have a little more to share. Stay tuned!