Webinar: MEF Explained

In the process of updating my Exploring .NET course for DevelopMentor, I’ve authored a module on the Managed Extensibility Framework, or MEF for short. I also presented a webinar on the topic.  Here is the recorded video, plus the slides and code.

Glenn Block, the principal architect of MEF, has written a very good article on MEF in the Feb 2010 issue of MSDN Magazine, where he provides plenty of code samples.  Rather than repeating those here, I’ll limit myself to explaining the overall architecture of MEF and how the various pieces fit together.

First of all, MEF ships both with .NET 4.0 and Silverlight 4 and allows you to build pluggable applications that can be extended either in-house or by third parties.  A good example is the code editor in Visual Studio 2010, which has been MEF-ified to allow for customized extensions.  The idea here is that you have some interfaces in a common assembly that are shared between plugin authors and the  main application.  However, instead of the application calling CreateInstance from either Activator or Assembly classes, MEF essentially does it for you under the covers based on a pair of attributes working together: Import (on the consuming class) and Export (on the plugin class).

While MEF is good for plugins, it’s more general purpose in nature, enabling applications to be composed of loosely coupled components (where have we heard that before … COM, .NET).  You can split up your application into various parts that extend abstract base classes or implement a common set of interfaces, and then use MEF to assemble the parts as needed.  For example, you might want to deploy a version of your application, then incrementally build it out over time without having to redeploy the whole thing.

Another scenario would be  large Silverlight applications.  MEF is built into the latest version of Silverlight and allows you to package different parts of the application into several xap files, which can be downloaded asynchronously on demand.

Here are the major components of MEF and how they fit together (click to enlarge).

mef-arch

MEF is built on a Composition Primitives layer, which can be used to interoperate with an IoC container such as Unity, but the primary way most developers interact with MEF is through a set of attributes and some bootstrapping code.  Basically, the consuming class decorates a property with an Import or ImportMany attribute, while the plugin class is decorated with an Export attribute.  As a parameter each takes a contract type, which is usually an interface or base class that placed in a shared assembly.

The bootstrapping code usually consists of one ore more catalogs, whose job it is to discover parts, either in an assembly, a file directory or perhaps a Silverlight xap file.  If more than one catalog is required, they can be part of an aggregate catalog.  The catalog is then passed to a composition container, which then supplies exported parts to imports based on the common contract.

Sounds pretty simple, eh?  However MEF comes with a few bells and whistles as well.  One of those is the concept of metadata.  In other words, exports can expose a dictionary of values via a MetadataExport attribute.  Imports can use a specialized Lazy<T, TMetadata> type to examine the part metadata and only create the part if it meets certain conditions.  The dictionary is <string, object>, but you can add type safety by creating a custom export attribute and a companion interface.

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class)]
public class ExportLoggerAttribute : ExportAttribute
{
    public ExportLoggerAttribute()
        : base(typeof(ILogger)) { }

    public ConsoleColor BackColor { get; set; }
}

 

[ExportLogger(BackColor=ConsoleColor.Yellow)]
class BlueLogger : ILogger { … }
 

 

public interface ILoggerMetadata{    // Must match attribute property    ConsoleColor BackColor { get; }}

 

class Worker
{
    [ImportMany]
    public List<Lazy<ILogger, ILoggerMetadata>>         Loggers { get; set; }

    public void DoSomething(string message,         ConsoleColor backColor)
    {
        foreach (var logger in Loggers)
        {
            if (logger.Metadata.BackColor == backColor)
                logger.Value.Log(message);
        }
    }
}

 

MEF also supports the  idea of dynamic recomposition at runtime, which enables exports to be instantiated while the host application is still running.  You have to opt-in to recomposition by adding a named parameter, AllowRecomposition=true, to the Import attribute.  Then you have to call ComposeParts on CompositionContainer, instead of SatisfyImportsOnce.  Lastly, you need to take some action to refresh the parts catalog.  For example, by calling Refresh on a directory catalog, or DownloadAsync on a Silverlight Deployment catalog.

That pretty much summarizes the main features of MEF. As you can see, the programming model is quite straightforward, and the capabilities are focused on a few features.  MEF is not designed to take the place of products like Managed Addin Framework, Unity or Prism.  If you need more bang for the buck, be sure to check those out.

About Tony Sneed

Sr. Software Solutions Architect, Hilti Global Application Software
This entry was posted in Technical and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.