I recently read an article on Dr. Dobb's that shows how to do something very neat: make plugins for an application using IronPython. This is something that I have been looking at for a while now, in no small part because one day I would like to write a CRM or CMS system that is easily extensible. In this example, authors Gigi and Saar Sayfan used the Managed Extensibility Framework (MEF) to handle the plugins. I had heard of MEF before, but I had thought for a long time that it was merely the system for writing Visual Studio 2010 plugins. As it turns out, anyone can use MEF to allow their application to use plugins.
When you want to use MEF, you need to create four separate things in your code. First, you need to make contracts that define how the different pieces work with each other. Next, you write "composable parts" that export and import functionality. Exporting makes the code visible to other parts and the application itself, while importing allows a part to make use of the functionality of other parts. The parts then get loaded into a catalog, which searches a location and loads all parts that adhere to the contract into itself. Finally, your application makes a container that gets the parts from catalogs and makes them available to the application.
This is not as complicated as it sounds. It took me a good deal of reading to really grasp how the system works, but it actually is pretty straightforward. The contract is essentially an interface, with some decorators to let MEF know what is happening. In fact, it is quite common for the composable parts to define their contracts as interfaces or abstract classes. The part itself is a piece of code written externally from the application that is getting loaded dynamically at runtime, and because of the discovery that the catalog provides, the application knows that it can call into the part without having interaction problems.
The catalog's role is finding and loading parts that meet the specified contract. Out of the box, catalogs can load parts from directories and assemblies, or aggregate multiple catalogs into one. Silverlight applications can also download XAPs to load into catalogs. And, you can always write your own catalog system. The catalog can inspect metadata on the parts so that the catalogs can be queried and filtered, which makes it easy to put together a user interface for selecting plugins (like Visual Studio 2010 does).
MEF is not the only way to do this. You can dynamically load an assembly and call into it if you want. Another option is to write the plugins in IronRuby or IronPython and call the code at runtime using the appropriate scripting host. Web services are often an option as well, and can be a much better choice depending on the scenario. And in many situations, those options may be better for you.
Where MEF stands out is when you want to expose an API to someone other than your team and allow them to write code that interacts with your application. In many ways, the model is quite similar to a web service; you have a lot of functionality under the hood, but have defined explicit, constrained ways of accessing it, and as a result both sides can work with each other and dynamically discover the capabilities.
MEF is an interesting system for developers to expose an API. Again, it is hardly the only option, but if you are looking to give your users or third-party developers an interaction point with your application, it is a great choice to consider.
Justin James is the Lead Architect for Conigent.