One of the less-talked-about features of Silverlight 4 is the new Managed Extensibility Framework, or MEF. MEF has been evolving on CodePlex for a while now. It’s slated to be integrated into .NET 4.0 and Silverlight 4, and as such is something with which developers should be familiar.

As its name implies, MEF is a framework for building extensible applications. It provides infrastructure for loose coupling between components and can be used to create composable applications—apps that pull together “parts” from various locations to compose an aggregate to present to the user. One of the key concepts in MEF is that of the catalog, which tells MEF where to look for parts that make up an application. An application can import parts from the catalog with [Import] attributes, and parts themselves can use [Export] attributes to expose themselves to importers. That’s the big picture, and of course it ignores hundreds of little details, but understanding these core concepts is a big help in understanding MEF as a whole.

To demonstrate how Silverlight developers might use MEF in a somewhat real-world scenario, I built a sample application named MEFDemo, which you can download from Wintellect’s Web site. MEFDemo is an extensible Silverlight 4 image editor. You load photos into it through an OpenFileDialog, and then you click buttons to apply filters of various types to the photos. Here’s MEFDemo showing a photo I snapped in the Vatican a few years ago:

MEFDemo before filtering

 And here’s how it looked after I clicked the Blur button a few times and then embossed the image:

MEFDemo after filtering

Out of the box, MEFDemo offers three image filters: a grayscale filter, a blur filter, and an embossing filter. Because the filters are MEF plug-ins, you can easily write filters of your own and plug them into the application.

One of the filters—the grayscale filter—is embedded in the main application. It’s found in GrayscaleFilter.cs and it implements an interface named IImageFilter:

public class GrayscaleFilter : IImageFilter

{

    public string Label

    {

        get { return “Grayscale”; }

    }

 

    public void Execute(WriteableBitmap bitmap)

    {

     

    }

}

IImageFilter is defined a separate project named ImageFilterContract and is decorated with an [InheritedExport] attribute, which means all types that implement the interface should be exported by MEF:

[InheritedExport]

public interface IImageFilter

{

    void Execute(WriteableBitmap bitmap);

    string Label { get; }

}

The other two filters are exported from a separate project named ConvolutionFilters. Because the project type is Silverlight Application, not Silverlight Class Library, building the solution places two XAP files in the Web site’s ClientBin folder: MEFDemo.xap, which contains the main application, and ConvolutionFilters.xap, which contains BlurFilter and EmbossFilter. These filters, too, implement IImageFilter and are automatically exported from the XAP as a result of the [InheritedExport] attribute.

In MEF terminology, the exported image filters are “parts.” Which begs the question: how and where do the parts get imported?

Look in MainPage.xaml.cs and you’ll find the following property declaration:

[ImportMany(AllowRecomposition = true)]

public ObservableCollection<IImageFilter> Filters { get; set; }

The [ImportMany] attribute tells MEF to look for all exported parts that implement IImageFilter and to populate the ObservableCollection with references to those parts. In MainPage’s constructor, a single line of code binds the ObservableCollection to an ItemsControl to produce buttons representing the imported image filters. The ItemsControl uses the following item template to create the buttons:

<ItemsControl.ItemTemplate>

    <DataTemplate>

        <Button Content=”{Binding Label}” Width=”96″ Height=”32″

            Margin=”0,12,12,12″ Tag=”{Binding}” Click=”OnExecuteFilter” />

    </DataTemplate>

</ItemsControl.ItemTemplate>

The text on the face of each button comes from the associated image filter’s Label property, and the Tag property holds an IImageFilter reference to the filter itself. When a button is clicked, it’s a simple matter to retrieve the IImageFilter reference and use it to invoke the filter:

IImageFilter filter = (sender as Button).Tag as IImageFilter;

filter.Execute(_bitmap);

With MEF, we can export parts and we can import parts. But how does MEF know where to look for parts to satisfy our imports? The answer is found in MainPage’s constructor:

// Create a catalog and add this XAP to it

PackageCatalog catalog = new PackageCatalog();

catalog.AddPackage(Package.Current);

 

// Download additional XAPs and add them to the catalog

Package.DownloadPackageAsync(new Uri(“ConvolutionFilters.xap”, UriKind.Relative),

    (s, p) => catalog.AddPackage(p));

           

// Pass the catalog to the MEF and compose the parts

var container = new CompositionContainer(catalog);

container.ComposeParts(this);

The first line creates a package catalog. The second line adds the current package (MEFDemo.xap) to the catalog, which allows MEF to find the GrayscaleFilter class exported from MEFDemo.xap. The third line initiates an asynchronous download of ConvolutionFilters.xap and adds it to the catalog when the download completes. This allows MEF to find the BlurFilter and EmbossFilter classes in that XAP. Adding image filters to the application is as simple as placing additional XAP files containing the filters in ClientBin and adding one line of code per XAP to download the package and add it to the catalog. Once filters are exported and added to the catalog, buttons representing them will automatically show up in the UI.

This example demonstrates the basics of MEF, but it could go even further. For example, MEF allows you to attach metadata to parts, and to read that metadata without instantiating the parts. Rather than use a Label property to expose text for buttons, image filters could use metadata instead. Glenn Block of Microsoft discusses metadata and lazy loading of imported types in Building Hello MEF Part II. Glenn’s blog is a great source of information on MEF, as is Jeremy Likness’s blog, which is currently exploring the integration of MEF and Prism. In addition, Mike Taulty has posted a great series of video tutorials on Silverlight MEF on Channel 9.

MEF makes composability a first-class citizen in Silverlight, and it’s going to be interesting to see how much of an impact it has on Silverlight design and development. One thing’s for sure: there has never been a more exciting time to be a Silverlight programmer!