MEF: Taking extensibility to the next level - Rudi Grobler

MEF: Taking extensibility to the next level

 

The Managed Extensibility Framework (MEF) is a new library in .NET that enables greater reuse of applications and components. Using MEF, .NET applications can make the shift from being statically compiled to dynamically composed. If you are building extensible applications, extensible frameworks and application extensions, then MEF is for you.

One of the common problems I currently face with the WPF Themes project is how do I allow people to submit themes? How do I then consume these themes? Currently the only option is to add your theme to the WPF.Themes library… This sucks!

[NOTE] This is a spike… just to proof the concept and is NOT included on the codeplex site for WPF Themes

Introducing MEF – MEF allow me to create a common contract that all themes should implement, here is my contract

Contract

Composable Parts do not directly depend on one another, instead they depend on a contract, which is a string identifier. Every export has a contract, and every import declares the contract it needs. The container uses the contract information to match up imports to exports. If no contract is specified, MEF will implicitly use the fully qualified name of the type as the contract. If a type is passed, it will also use the fully qualified name.

public partial class Theme: System.Windows.ResourceDictionary
{
    public string FriendlyName { get; set; }
}

Composable Parts - ExpressionDark

A Composable Part is a composable unit within MEF. Composable Parts export services that other Composable Parts need, and import services from other Composable Parts. In the MEF programming model, Composable Parts are attributed with the System.ComponentModel.Composition.Import and [System.ComponentModel.Composition.Export] attribute in order to declare their exports and imports. A Composable Part should contain at least one export. Composable Parts are either added to the container explicity or created through the use of catalogs. The default catalogs that MEF ship with identify Composable Parts through the presence of an export attribute.

XAML

<common:Theme x:Class="WPF.Themes.ExpressionDark.Theme"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:common="clr-namespace:WPF.Themes.Common;assembly=WPF.Themes.Common"              
    FriendlyName="ExpressionDark">
    
    <!-- The theme stuff should go here... -->

</common:Theme>

Code-behind

[Export(typeof(WPF.Themes.Common.Theme))]
[ExportMetadata("Name", "ExpressionDark")]
public partial class Theme : WPF.Themes.Common.Theme
{
    public Theme()
    {
        InitializeComponent();
    }
}

All that the theme developer now need to do is use this as a basis for his theme! My WPF.Themes.Common.Theme derives from ResourceDictionary. The magic of MEF happens with the Export attribute. Now we have our theme nicely package into its own dll (ExpressionDark.dll).

Catalogs

One of value propositions of MEF's attributed programming model is the ability to dynamically discover exports via catalogs. Catalogs allow applications to easily consume exports that have self-registered themselves via Export attributes. Below is a list the catalogs MEF provides by default.

 

 

We will be using the DirectoryPartCatalog. The DirectoryPartCatalog scans a directory for composable parts. The other cool thing about DirectoryPartCatalog is that you can also set it to “watch” the given directory…this will then notify you if new themes gets dropped into the themes directory (Check out this demo of how this is used in BabySmash)

ComposablePartCatalog catalog = new DirectoryPartCatalog("Themes", true);

Container

CompositionContainer container = new CompositionContainer(catalog);

From what I understand, the container holds all the par definitions (not the actual composable parts). If you need a part, query (via the container) for it

System.Collections.ObjectModel.Collection<Theme> themes = container.GetExportedObjects<Theme>();

Here I am explicitly fetching all the themes found in the directory

Please note that this is still experimental but I thought it might be useful to share this work to get some early feedback! I would love to hear your opinions about this approach! Is MEF the future?

Read more

If you found this useful or interesting, please kick it on DotNetKicks.com

Published Thursday, December 04, 2008 10:04 AM by rudi

Comments

# MEF: Taking extensibility to the next level

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Thursday, December 04, 2008 10:07 AM by DotNetKicks.com

# re: MEF: Taking extensibility to the next level

Very nice Rudi. This is going to take me a bit of time to digest, but it seems to be a really nice implementation.

Thursday, December 04, 2008 10:58 AM by Pete O'Hanlon

# Dew Drop - December 4, 2008 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop - December 4, 2008 | Alvin Ashcraft's Morning Dew

Thursday, December 04, 2008 2:07 PM by Dew Drop - December 4, 2008 | Alvin Ashcraft's Morning Dew

# 2008 December 08 - Links for today &laquo; My (almost) Daily Links

Pingback from  2008 December 08 - Links for today &laquo; My (almost) Daily Links

# MEF for Loading themes/resourceDictionaries

Hmm... One more acronym to remember :).. "The Managed Extensibility Framework (MEF) is a new library

Tuesday, December 30, 2008 5:54 PM by Lester's WPF blog