MEF Container - encapsulating and simplifying

by 21. August 2010 14:19

With MEF 2 Preview 1 released (July 2010) it is time to dig in and examine it under the hood, particularly .NET 4.0 capabilities.   Fortunately the Patterns & Practices teams have a standard of providing unit test which make the task sometimes easier than reading (or waiting on) the documentation.

I'll start from the top and work my way down - I am currently on the System\ComponentModel\AttributedModel\AllowNonPublicCompositionTests.cs

        [TestMethod]
        public void PublicFromPublic()
        {
            var container = ContainerFactory.Create();
            CompositionBatch batch = new CompositionBatch();
            var importer = new AllPublicImportOnly();
            batch.AddPart(importer);
            batch.AddPart(new AllPublicExportOnly() { ExportA = 5, ExportB = 10 });
            container.Compose(batch);
            Assert.AreEqual(5, importer.ImportA);
            Assert.AreEqual(10, importer.ImportB);
        }

Up to this point my adventures with MEF have been confined to the attributes import, export, etc.   I was encourage early in the game to see programmatic support for MEF.  My objective now is to understand MEF from this angle so that I create a Unity Strategy for Prism that will permit Prism, Unity and MEF to play nicely under one roof.  Since I learn by doing I decided to create a MEFContrib project that will simplify life (while making it easier to understand the code).   The MEFContainer and CompositionBatchExtension classes are the first classes added to this project.

For example, the following code performs the exact same process as the above code:

        [TestMethod]
        public void PublicFromPublicUsingMEFContainer()
        {
            var importer = new AllPublicImportOnly();
            var exporter = new AllPublicExportOnly{ ExportA = 5, ExportB = 10 };
            new MEFContainer()
                .AddPart(importer)
                .AddPart(exporter)
                .Compose();
            Assert.AreEqual(5, importer.ImportA);
            Assert.AreEqual(10, importer.ImportB);
        }

The above was Added to AllowNonPublicCompositionTests.cs after adding reference to MEFContrib.

The contents of MEFContrib follow:


using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace MEFContrib.Base
{
    /// <summary>
    ///  MEF Container
    /// </summary>
    public class MEFContainer
    {
        private CompositionBatch batch = new CompositionBatch();
        private CompositionContainer container = new CompositionContainer();
        /// <summary>
        /// Adds the part.
        /// </summary>
        /// <param name="part">The part.</param>
        /// <returns></returns>
        public MEFContainer AddPart(object part)
        {
            batch.AddPart(part);
            return this;
        }
        /// <summary>
        /// Composes this instance.
        /// </summary>
        public void Compose()
        {
            container.Compose(batch);
        }
    }
}

namespace MEFContrib.Base.Extentions
{
    public static class CompositionBatchExtension
    {
        /// <summary>
        /// Composes the specified batch.
        /// </summary>
        /// <param name="batch">The batch.</param>
        /// <param name="container">The container.</param>
        /// <returns></returns>
        public static MEFContainer Compose(this MEFContainer container)
        {
            container.Compose();
            return container;
        }
    }
}

Tags: ,

MEF

Notice

Blog videos and references to CodePlex projects are no longer valid