Recently I got the chance to explore one of the features of .net 4 that I had not had a chance to use, and that was MEF. MEF stands for Managed Extensibility Framework. It was introduced to work with MAF (Managed Add-In Framework), while MAF concentrated on extension isolation and assembly loading and unloading, MEF has more of a focus on discovering and extending our applications.
What is MEF?
According to MSDN, MEF is the following:
The Managed Extensibility Framework or MEF is a library for creating lightweight, extensible applications. It allows application developers to discover and use extensions with no configuration required. It also lets extension developers easily encapsulate code and avoid fragile hard dependencies. MEF not only allows extensions to be reused within applications, but across applications as well.
I think the above is a very good definition. However to go further into the topic, MEF is a library that is part of the .net framework, so we can certainly trust it. It uses attributes to define whether a class is exported from it’s library, and therefore can be discovered by MEF, and it allows the classes to state what contract they adhere to (usually a defined interface from our application). We can then write code to discover classes that implement our defined classes, and then use them in our main application.
That may sound a bit confusing, but simply put, this is allowing external libraries to provide additional functionality to our applications by acting as plugins. MEF handles all the hard work, and we can just focus on our application logic
Where would I use MEF?
Microsoft again give a very good example for this. The sample application for MEF is a simple calculator application. It processes an input, and separates it into numbers, and operators. Operators may be defined by plugins. By using MEF, the simple calculator is very powerful, not only separating out the logic from the actual functionality, but it allows third parties to write their own operators for their own specific purposes. It also allows us to reuse the basic calculator code in many different scenarios, for example we could write a science focused calculator, a maths focused calculator, or even some entirely new type of calculator, with our own custom defined operators.
The scenario where I recently used MEF is another good example. I need to write an application to pull files from several locations, and then convert them into a standard file format. I wanted to write something very generic, as the premise of the application was very simple, and could be applied to many cases. I split the application into two parts, retrieving files from a source, and then converting and saving those files to the standard type. By using MEF, I defined the simple logic of the application like this, and then used plugins to implement the functionality. This now meant the same application could be used to retrieve files from any source (directory structure, exchange, web service), and would allow me to write plugins for future potential sources. Similarly I can convert any file type into another file type, by just writing a plugin to do so. Combining these two, such a simple application is now extremely powerful, and has great potential for reuse in new applications.
Is it complicated?
Short answer, no. MEF requires just a few lines of code to setup and the rest is done through attributes. Certain things can catch you out though. Even if a DLL is loaded using MEF at runtime, the DLL file is locked whilst the application is open, even if it is not being used anymore. This could cause an issue if you wanted to be able to upgrade a plugin whilst the application was running. However by creating a separate AppDomain for your plugins to run in, and unloading it when done, this then keeps the DLL files unlocked after use, and allows you to upgrade. It sounds fairly complicated, but is actually again just a few lines of code to achieve.
MEF is an excellent tool for writing generic systems, and enabling extensibility in your applications. It is very trustworthy, being part of the .net framework, and is also far easier than you might imagine. I cannot promote enough the benefit of thinking about every system in a generic way, as it allows many extra potential applications for most systems, and will save you time, and enable you to avoid code reuse across systems. MEF is an excellent tool to help with this.
I will aim to produce a simple tutorial for MEF in my next blog post to give context to how and why you would use it. I see many potential applications for this framework in the future systems I write, so I would also encourage you to explore the possibilities.