First look at Managed Extensibility Framework (MEF)

Microsoft’s solution for dependency injection is called Managed Extensibility Framework (MEF). Dennis presented about this on the Techdays 2015. Now it is time to look at this myself with a simple demo app.

Demo app

I’ve created a demo app to play with MEF. The class diagram is below. Program in MEFDemo will create a MachineChecker (that takes INetwork as parameter in the constructor) and call the Check method.
MEFDemo_ClassDiagram

Next I will show the different classes. A complete working sample is for download at the end of this post.

Util

The Network class implements the INetwork interface. By putting Export on the type MEF can handle it.

[Export(typeof(INetwork))]
public class Network : INetwork {
   // implementation
}

The implementation uses System.Net.Dns, but it’s irrelevant for my demo.

Proxy

Like above the MachineChecker class needs the Export attribute. To instruct MEF how to construct the class I need to put the ImportingConstructor attribute on the constructor, since there is always a default constructor.

[Export]
public class MachineChecker {
   [ImportingConstructor]
   public MachineChecker(INetwork network) { 
      // implementation
   }
   // implementation
}

An interface would make replacing the MachineChecker easier.

Program

Now in the Main I’ll create a container to wire up the classes. Then pass the container to the Run method.

public static void Main(string[] args) {
    var catalog = new AggregateCatalog();
    var assemblyDirectory = ".";
    catalog.Catalogs.Add(new DirectoryCatalog(assemblyDirectory));
    var container = new CompositionContainer(catalog);
    Run(container);
    Console.ReadLine();
}

public static string Run(CompositionContainer container) {
    var machineChecker = container.GetExport<MachineChecker>();
    var check = machineChecker.Value.Check("localhost");
    return check;
}

The container.GetExport returns a Lazy as in lazy loading. The value property contains the object MEF has constructed with INetwork as parameter.

Unit test

Isolating object for unit testing is easy when using dependency injection. The ComposeExportedValue extension is in the System.ComponentModel.Composition namespace.

using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

private CompositionContainer CreateIsolatedContainer() {
    var fakeNetwork = MockRepository.GenerateStub<INetwork>();
    var catalog = new TypeCatalog(typeof(INetwork), 
        typeof(MachineChecker));
    var container = new CompositionContainer(catalog);
    // inject the stub here
    container.ComposeExportedValue<INetwork>(fakeNetwork);
    return container;
}

In the code coverage you’ll see that Network is not used since it is replaced by the stub. Also the Main method is not called by the unit tests.
mefdemo_code_coverage

Conclusion

Dependency injection makes applications easier to unit test. Now it is part of the .NET framework (since v4.0), that’s one reason less not to use it.

References

About erictummers

Working in a DevOps team is the best thing that happened to me. I like challenges and sharing the solutions with others. On my blog I’ll mostly post about my work, but expect an occasional home project, productivity tip and tooling review.
This entry was posted in Development and tagged , , , . Bookmark the permalink.

1 Response to First look at Managed Extensibility Framework (MEF)

  1. jokelab says:

    Nice and clear example!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.