Tuesday 26 January 2010

MEF4

There is a great set of Webcasts on application of MEF4 in Silverlight applications

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/12/31/silverlight-4-screencasts-the-managed-extensibility-framework-mef.aspx

I have reproduced the examples in this set of webcasts. Now I would like to do exactly the same but with a WPF application. Unfortunately the .net assemblies that come with vs2010 Beta 2 do not include System.ComponentModel.Composition.Initialization.dll. When I try to use the DLLs from the Silverlight SDK in a WPF application I get a System.Windows.Markup.XamlParseException.

It is only a matter of time before this will be available also for non Silverlight applications. I have asked a question concerning this in

http://social.msdn.microsoft.com/Forums/en-US/MEFramework/thread/7eeabad4-73db-4f57-a01a-2b326b90b129

Here’s an example from this set of webcasts of the kinds of things that MEF4 can do in the way of dependency injection:

Here is an interface describing what it means to be a TextEngine:

using System;
namespace SilverlightApplication1
{
    public interface ITextEngine
    {
        string Name { get; }
        void ProcessText(string text);
    }
}

Here are 2 implementations of the Text Engine

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;

namespace SilverlightApplication1
{
    [Export(typeof(ITextEngine))]  // Means I am a composable component
    public class TextEngine : ITextEngine
    {
        public string Name
        {
            get
            {
                return "default";
            }
        }
        public void ProcessText(string text)
        {
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;

namespace SilverlightApplication1
{
    [Export(typeof(ITextEngine))]
    public class FancyTextEngine : ITextEngine
    {
        public string Name
        {
            get
            {
                return "FancyDefault";
            }
        }
        public void ProcessText(string text)
        {
        }

    }
}

Here is an implementation of a Word processor that consumes the Text Engines

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;

namespace SilverlightApplication1
{
    [Export]  // Means I am a composable component
    public class WordProcessor
    {
        [ImportMany]
        public IEnumerable<ITextEngine> TextEngines { get; set; }
    }
}

Finally here is an application that consumes the WordProcessor

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.ComponentModel.Composition;

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        [Import] // Menas this class needs a WordProcessor
        public WordProcessor WordProcessor { get; set; }

        public MainPage()
        {
            InitializeComponent();
           PartInitializer.SatisfyImports(this);
        }

    }
}

MEF resolves the imports and exports on the line PartInitializer.SatisfyImports(this);

MEF4 is really a useful tool for decoupling with dependency injection, there are many places where customization is possible. For example components can be lazy loaded, it is possible to set constructor parameters, the containers can be configured so that the source of assemblies can be customized, custom compiler attributes can be used to set metadata that can be used to make readable use of specialized components etc etc.

The web casts are really worth watching.