MEF is the Framework which allows you to load extensions to you application easily. It does discovery and composition of parts you need to be included in your application at run-time. You could extend your behavior simply with adding new Plugin. Managed Extensibility Framework will do everything for you.

Hello MEF World!

Assume we have really simple application and we want it to say “Hello MEF World!“:

    class Program
    {
        static void Main(string[] args)
        {
            var program = new Program();
            program.Run();
        }
        private void Run()
        {
            ProgrammGreeter.SayHello();
        }
        protected IGreeter ProgrammGreeter{ get; set;}
    }
    public interface IGreeter
    {
        void SayHello();
    }
    public class Greeter:IGreeter
    {
        public void SayHello()
        {
            Console.WriteLine(“Hello MEF World!”);
        }
    }

That is absolutely how this look and we want to make this work. The main issue is to have instance in property ProgrammGreeter to be real instance of Greeter.

Lets accomplish this with MEF

In order to do this we need to include reference to System.ComponentModel.Composition.

Accordingly to MSDN: “MEF is an integral part of the .NET Framework 4 Beta 1, and is available wherever the .NET Framework is used. You can use MEF in your client applications, whether they use Windows Forms, WPF, or any other technology, or in server applications that use ASP.NET. In addition, there are plans to add MEF support for Silverlight applications.

Most likely MEF will be included into .NET Framework 4.0, but for now we could download it from codeplex site here.

Once we added reference we could add Import and Export attributes.
Export stands for exposing some capabilities and Import stands for dependency on some other capability.

Our Greeter provides some capabilities so we add Export there:

    [Export(typeof(IGreeter))]
    public class Greeter : IGreeter

We want to use that capability in our Programm class, we depend on that functionality. Add Import:

        [Import]
        protected IGreeter ProgrammGreeter { get; set; }

Usually our capabilities lives in other asseblies, but also they could live in called assembly. Anyway we need to say how to compose all our dependencies to MEF.
This could be done with method Compose which we be calling before we are using capabilities, usually at the start of app:

        private void Run()
        {
            Compose();
            ProgrammGreeter.SayHello();
        }
        private void Compose()
        {
            var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var compositionContainer = new CompositionContainer(assemblyCatalog);
            compositionContainer.ComposeParts(this);
        }

I ran my application and got:

How does Managed Extensibility Framework work?

I think that you are bit concerned/confused regarding that Compose method. Just read comments in code of Compose, which I made more detailed:

        //We need guide MEF how to Compose all we need
        private void Compose()
        {
            //Catalog says where to search for capabilities (Where do exports live)
            var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            //CompositionContainer holds defined dependencies and coordinates creation
            var compositionContainer = new CompositionContainer(assemblyCatalog);
            //CompositionBatch object holds references to all objects that need to be composed
            var compositionBatch = new CompositionBatch();
            //one of such objects is Programm instance (this), it needs to be composed
            compositionBatch.AddPart(this);
            //And finally Container has method called Compose to do actuall Composing
            compositionContainer.Compose(compositionBatch);
        }

In Managed Extensibility Framework there are primitives called ComposablePart which holds extensions to your application grabbed from Catalog. But also it might be that they have Imports which also needed to be composed.

Take a look on this picture from Managed Extensibility Framework wiki page.

More complex Example

In this example we will have application which parses XML file (contains information about some developer). Then when we want to deploy our application to Clients we want that XML to pass some rules, but they could differ from Client to Client. To accomplish this we put rules into separate dll and will work with it as with plugin.

We have two assemblies:

  • MEF.DEMO which declares ISecurityRule and IDataRule.
  • MEF.Rules has implementation of those interfaces.

Like on picture below. I simply don’t want to bore you with explaining of Rules logic. If you want sources just ping me.

Our Programm class wants to load rules from other assembly so we put Imports.

        [Import]
        public ISecurityRule SecurityRule { get; set; }
        [ImportMany]
        public IDataRule[] DataRules { get; set; }
        public void Run()
        {
            Console.WriteLine(“Programm run.”);
            Compose();
            Console.WriteLine(“Composition completed.”);
            var document = XDocument.Load(“developer.xml”);
            Console.WriteLine(document.ToString());
            var passesValidation = SecurityRule.PassesValidation(document);
            Console.WriteLine(string.Format(“Rule {0}: {1}”, SecurityRule.GetType(), passesValidation));
            foreach (var d in DataRules)
            {
                var valid = d.IsValid(document);
                Console.WriteLine(string.Format(“Rule {0}: {1}”, d.GetType(), valid));
            }          
        }

As you noticed we are using ImportMany, name says for itself.

We need to change our Compose method to search for Exports in Directory where execution assembly is located. For that we use DirectoryCatalog.

        private void Compose()
        {
            var catalog = new DirectoryCatalog(Environment.CurrentDirectory);
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }

Put those dlls in one folder, and run MEF.DEMO. You will get:

The goal of MEF is to seamlessly glue together classes which import services from other parts of the application, and some classes which export those services. You could say that MEF is like DI container. Yes it has a lot of it, but Managed Extensibility Framework is concentrated on composition. And that composition could be done at run time at any point of time you want that to happen. Also you could do re-composition whenever you want to do that. You could load capabilities with Lazy technical or add some metadata to your exports. Discovering of dependencies in Catalog could be done with Filtering.

Managed Extensibility Framework is great feature, that Microsoft added to .NET 4.0 Framework.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someone