Tutorial on creating loosely coupled applications with MEF
When I first read about MEF (Managed Extensibility Framework), I thought it was a great concept to create plugin-based applications, allowing customers to customize some behavior of the application for instance. Putting the whole concept into reality is something different, so in this article I will give a brief overview of the steps to take to get started with MEF. I suggest to create three different assemblies to distinguish between their functionality:
- A project defining the contracts
- A project implementing the contracts
- A project consuming the contracts
In some way you could compare this to WCF, but apart from that there are no other analogies to be made between these two. Now, in the consuming project (let’s make it a good old console application) you must only reference the interfaces projects and not the actual implementation. If you do this, you just ignore the entire idea of MEF (which is discovery of implementations at runtime)! Next up, define your interfaces. Just like WCF, you define which methods should be supported by the implementing assembly so it should be generic at best. Once you have done that, let’s go over to the actual implementation of the interface. In the corresponding project, reference the interface assembly you just created and create some classes that inherit from them (and give them some content). Do the exact same thing all over again so you will end up with two projects implementing the interfaces. Don’t forget to mark the implementing classes with the MEF - export attributes:
The first attribute is necessary, the second one is not. Based on your preferences, you can define whether to share the assembly or make it private. Everything is now in place for resolving the contracts with the implementation at runtime, by using the following code below. To get started quickly, let this code run as the first thing in the console application:
This code will load the assemblies that have classes which have been marked with the MEF export attributes. In order to get this working, you will need to build your implementing assembly and paste it into the bin directory of your console application as the MEF container will be looking in that directory.
Note: for now do this only for one implementing assembly, not both (this is also a possibility in MEF to load multiple assemblies but that’s out of scope here).
This will load the MEF container but it won’t yet create new instances of your interfaces. In order to do that, you will need to call code similar to this (with T being the interface you want to get):
If this line doesn’t crash, try the method that your interface defines. If that works too, you are there! Congratulations, you just got your first steps in the world of MEF! Now remove the implementing assembly from the bin directory and replace it by the DLL from the other one and restart your console application. If you have done everything right, you should get another result. That is just a very basic example so please note that MEF is much more stronger. It is possible to inject parameters and load multiple assemblies for instance. I understand that this technology can be somewhat confusing or daunting at first, but once you get the hang of it, it is really not that hard. That’s why I deliberately didn’t go into too much detail as I have had the same struggle before, and I’m happy to have played around with it for some time now.