Managed Extensibility Framework (MEF) - Microsoft's Official Inversion of Control Container

Please note that this post was migrated to my new blog platform. There may be bad formating, broken links, images, downloads and so on. If you need an item on this page, please contact me and I will do my best to get it from my backups.

~E

This new Microsoft feature in .NET Framework 4 is a programming model for reusing components, very similar to those Inversion of Control container frameworks out there that we all know and love (Castle Windsor, Structured Map, their own Unity from the Patterns and Practices team and etc).  Now, they have built their own to address the pain points of these frameworks called the Managed Extensibility Framework, or MEF for short.

I was pleasantly surprised this weekend when reading the February 02010’s issue of MSDN Magazine.  Getting up-to-speed on some new features in .NET Framework 4, I saw the headline “Building Composable Apps in .NET 4 with the Managed Extensibility Framework” by Glenn Block.  Yeah, it just rolls off your tongue eh?  So I decided I had a few minutes while waiting for the water to boil and scanned the article.  I am glad I did.

In this post, I will try to give a very brief overview on how to use MEF coming from a background of using other Inversion of Control (IoC) containers, including some of the gotchas that you must be aware of during the switch.  Yeah, you will want to make the switch – the switch away from those other bulky frameworks.  I, for one, am officially announcing my abandonment of Castle and Unity for all future projects.  Because once you add-in .NET 4’s new data annotations for seriously improved validation, mixed with MEF, the only other 3rd party component I am left with is Castle’s Logger abstraction – which I am hoping I can find a replacement for with .NET 4’s new features.

MEF Terminology

First and fore-most for those of you already using an IoC container, it’s time for a quick review on what MEF calls a few things and concepts.  Below is a table I whipped up to help compare the two terminologies (the MEF portions largely taken from Glenn’s excellent article).

 2-15-2010 10-41-32 PM

Below is an image from Glenn’s article that helps visualize the concepts above of MEF.

ee291628_Block_Fig1(en-us,MSDN_10)

You can see that the overall concept is called Composition.  A ‘part’ is the type or service you want to export.  The part (or parts) is marked for Export via Contracts (which are automatic).  And other parts that want to ask for another part can do so by Importing.

Managed Extensibility Framework – Why they built it

Glenn mentions in the article that they needed a way to compose of reusable types or components in the up coming Visual Studio 2010, Oslo, Acropolis and I am sure many more.  What is important to note is why they created one themselves, instead of using Unity or alike.  Glenn mentions some key points:

  • Third-party Extensibility (allowing vendors to generate plug-ins for Visual Studio, or your own application, with minimal work on your part now)
  • Other frameworks were too heavyweight for a simple programming model. 
  • Or other frameworks required too much effort on the part of either the host or the extension developer.

Those last two is what struck a cord with me, and got my attention.  Try to sit back and think about how you would allow your applications to be extended with Castle, StructureMap or even Unity.  That’s a lot of work, a lot of 3rd party assemblies to wire up and configure properly.  Especially if you want runtime changes, which MEF supports out of the box with no configuration.

That last point is particularly interesting.  All too often I see a released developer framework or contrib project by a group of inspired individuals.  This is great and all, but those projects quickly grow to be a large project requiring documentation, support, and even refactorings for performance.

It got me thinking a lot about what I see wrong with Castle – only two things, it’s learning curve and size.  While Unity was very well documented, it comes with some significant bloat and only what I can refer to as hoop-jumping.  The earlier versions of Unity violated Dependency Injection pricipals and concepts (no ctor injection!).  Perfect example of refactoring.

MEF really strives to resolve all of these issues, with some extremely simple programming models that I will show you below.

MEF Programming Models – Straight Attributed Declarations

Another rip from Glenn’s article.   But he did it so well.

Developers consume MEF through a programming model.  A programming model provides a means to declare components as MEF parts.  Out of the box, MEF provides an attributed programming model, which will be the main focus of this article.  That model is just one of many possible programming models that MEF enables.  MEF’s core API is completely agnostic to attributes.

Yep, you heard that right.  MEF supports Attributes – for out-of-the-box functionality.  No configuration, no setup, nothing.  This is so much easier than you are even thinking.  So much so, I feel guilty by writing all of this text.  Let’s just show you how it’s done now.

The Blog “Hello World” Snippets

As what seems to be an invasion, the common Hello World for websites these days are blogs.  So without further delay, here’s some code snippets.

The post object


public partial class Post
{

public Int32 PostId { get; set; }
public String Title { get; set; }
public String Description { get; set; }
public String Body { get; set; }
public Guid AuthorId { get; set; }

}

And the PostService that will service the post.


[Export(typeof(IPostService))]
public class PostService : IPostService
{
    [Import]
    public IPostRepository PostRepository { get; set; }

    public Post FetchById(Int32 postId)
    {
        return
            (from p in PostRepository.GetAll()
             where p.PostId == postId
             select p as Post).FirstOrDefault();
    }
}

Please note that the above code is not production-code.  You should always provide proper cache, concurrency and disposable patterns.  This code has been cleaned up for easier reading.

Notice that the PostService has been marked to be exportable, using a specific contract type for IPostService. Now, you do not have to specify the contract type or name. You can simply use [Export]. But remember, we do want to allow for simply extensibility in the future by plugging in different components to be served during composition.  How to do that?  Easy, just specify the interface type as the contract.  Now how easy was that?

Also, notice that we have a dependency on IPostRepository. This is marked with the simple [Import] attribute.  It does exactly as you think.  MEF composes the first part that matches the contract for IPostRepository and supplies it

Now, some will cry fowl here since I am not directly injecting IPostRepository, or not demanding it in the constructor. Yes, MEF fully supports constructor injection. But, there is a few gotchas you have to be aware of with MEF and constructor composition that I get into a little further down. There’s also a new pattern I am designing, when mixed with .NET 4 and some nifty T4 templates I’m tinkering with. That’s another article I’ll write though. Check the comments, or leave a comment for more information on, “Managing BDD Contexts and Mocks Automatically with .NET 4, MEF, and T4 Templates.” Nice. I just named my next blog post.

Constructor Dependency Injection - MEF Gotcha

As mentioned above, constructor injection is a bit tricky with MEF.  There are some rules to follow:

  • MEF assumes all parameters are imports, making the import attribute unnecessary.  I leave it up to the reader to figure out how to get around this.
  • Recomposition is not supported on constructor parameters.

That last one is almost a deal breaker for me.  Recomposition is a feature of MEF that allows parts to automatically have their imports updated as new matching exports appear in the system.  Given, this isn’t the case with most websites out there.  It’s an issue for websites and applications that want to support dynamic (e.g. downloadable) plugins.  The plugins would overwrite, at runtime, certain contracts and therefore allow the parts to automatically be updated with the new plugin versions - all without an application restart!

So with that said (and you will never be developing plugins right?), you can use constructor injection with MEF as follows.


[Export(typeof(IPostService))]
public class PostService : IPostService
{

private IPostRepository _postRepo;
private IUserRepository _userRepo

[ImportingConstructor]
public PostService(IPostRepository postRepo, IUserRepository userRepo)
{
    _postRepo = postRepo;
    _userRepo = userRepo;
}

public Post FetchById(Int32 postId)
{
    return
        (from p in _postRepo.GetAll()
         where p.PostId == postId
         select p as Post).FirstOrDefault();
}

}

Don’t fret too much though about the all-or-nothing constructor.  You have a Factory option later on in this post.

Bootstrapping MEF for Application Startup

Glenn nailed it right on the head when he called this procedure “bootstrapping.”  I’ve always struggled with the proper terminology for this composition process with other Inversion of Control containers.  Bootstrapping.  Yep, just like my hacked MP3 players have.

To get things up and running, you will need to to insert some bootstrapping code for your application.  This code is required with any type of IoC container, and with MEF as well.

Below is a small code snippet from a typical ASP.NET MVC 2 global.asax file.  Notice I added the two using blocks at the end of the Application_Start().  This process would be the same for any type of application you have.


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

protected void Application_Start() {

AreaRegistration.RegisterAllAreas();

RegisterRoutes(RouteTable.Routes);

using (var catalog = new DirectoryCatalog(@".\"))
{
    using (var container = new CompositionContainer(catalog))
    {
        container.ComposeParts(this);
    }
}

}

Now, this code is running from with the website assembly.  If you, like me, create a seperate assembly to hold your Domain and Repository models, then you simply reference the assembly by replacing the ‘this’ keyword with Assembly.GetAssembly(typeof(MyProject.Domain)).  And yes, you can reference multiple catalogs and assemblies and build up your list as well.

Note that I included the namespaces here.  This is important as normally this bootstrapping code is in the Hosting namespace.  What they don’t tell you is there is an extension in the namespace one higher for CompositionContainer, that enables the ComposeParts() extension method in the System.ComponentModel.Composition namespace.

There are tons of options here with the composition containers.  Please refer to the .NET 4 documentation on MEF, as well as Glenn’s article for a few more tips.  You can specify an assembly to reference for the catalog.  You can have aggregated catalogs for grouping/namespacing purposes.  And yet, you can still have that aged-old configuration file if you really really really want to manually register (export) each type.

All Parts are Singletons, out of the box

Yep.  All of your part’s instances are composed and referenced throughout all of your code as singletons (or “statics”).  This is a great solution for that stubborn developer you may have working in your group that just won’t let go of static managers.  Make it instance based, and slap an [Export] on it.  Done, now use [Import] wherever you like.

This is important to note because Castle and StructuredMap both default to transient composition (Unity uses whatever you configured the container to use as default).  So, make sure you are coding to be thread-safe if you are making the switch over to MEF.

But do not fret, it’s easy to specify the lifestyle within the contract definitions.  There are three possible configurations you can set with the [PartCreationPolicy()] attribute:

  • CreationPolicy.Shared (singleton, default)
  • CreationPolicy.NonShared (transient)
  • CreationPolicy.Any

The “Any” option is interesting as it leaves it up to the context configuration of the host and/or the configuration of the [Import] contract to specify.  You can use RequiredCreationPolicy on the [Import] contract definition to specify the preference.


[PartCreationPolicy(CreationPolicy.Any)]
[Export(typeof(IUserAccountService))]
public class UserAccountService : IUserAccountService
{

...

}

public class Post {

public Int32 PostId { get; set; }
public String Title { get; set; }
...

[Import(RequiredCreationPolicy=CreationPolicy.NonShared]
public IUserService UserService { get; set; }

}

There is a problem with this concept though.  With a current project we are working on at the moment, we identified the need to have a security context around our services to ensure the current WebRequest has the correct security credentials.  With this, we elected to use Castle’s WebRequest lifestyle feature.  Sadly, this is not possible (yet) with the PartCreationPolicy.  So it is left up to the implementer to handle custom composition on their own with a Factory pattern (see below).

Lazy Loading within Entities

Those of you that are wanting Lazy Loading within your entities, but are struggling with a solution that is compatible with Inversion of Control, fear not!  The answer is now possible with MEF.


public partial class Post
{

[Range(0, Int32.MaxValue)]
public Int32 PostId { get; set; }

[Required, StringLength(64, MinimumLength = 5)]
public String Title { get; set; }

[Required, StringLength(1024, MinimumLength = 5)]
public String Description { get; set; }

[Required, StringLength(Int32.MaxValue, MinimumLength = 5)]
public String Body { get; set; }

[Required]
public Guid AuthorId { get; set; }

[Import]
public IUserService UserService { get; set; }

private User _user;
public User Author
{
    get
    {
        if (_user == null)
            _user = UserService.FetchById(this.AuthorId);
        return _user;
    }
}

}

With our updated Post entity, notice we now have a dependency on IUserService marked with the [Import] attribute.  Yep, MEF composes that for you, and you have the UserService to access your lazy objects as needed.

Using MEF as a Static Wrapper

Time and time again I find myself writing wrapper classes around static members of a 3rd party component, just so I can unit test my code without having to rely on that static class.  Using MEF, if you haven’t guesses already, is just as easy as you might think.


public class Loggerpart
{

[Export]
public ILogger Logger
{
    get
    {
        return LogManager.GetLogger("LoggerInstance", "config");
    }
}

}

This pattern allows you to make a wrapper around any 3rd party or legacy code.

MEF Composition with a Factory Pattern

Here’s another one not in Glenn’s article.  How to use MEF with a factory pattern to initiate a complex type.


public class UserService : IUserService
{

public UserService(ISecurityContext securityContext)
{
    ...
}

}

public class UserServiceFactory {

[Export(typeof(IUserService))]
[PartCreationPolicy(CreationPolicy.Shared)]
public IUserService Instance
{
    get
    {
        var context = HttpContext.Current;
        var securityContext = 
            SecurityContextProvider.Setup(context)
        return new UserService(securityContext);
    }
}

}

Notice how the UserService is not exported?  Instead, we designate a property member of UserServiceFactory called Instance as the Export composition location. 

Remember, you are only Exporting for Composition at runtime.  Nothing gets composed during your unit tests, as you are mocking them.  So anywhere you use [Import] will be still be mockable for any of your unit tests with this pattern.

Exporting with Multiple Contracts

Here’s a nice trick, you can specify multiple Export contracts for multiple types.  Why would you do this?  If you are a big DDD follower, you may be using IUserService and IAccountService combined to give you an UserAccountService part.


[Export(typeof(IUserService))]
[Export(typeof(IAccountService))]
public class UserAccountService : IUserService, IAccountService
{

...

}

MEF Does Not Blow Up on Rejection

This one is going to take some getting used to.  As Glenn mentions, MEF does not throw exceptions if a part cannot be satisfied.  It simply will not exist in the object graph for MEF to return – you’ll get a null, and will most likely see a NullReferenceException in your containing code that is trying to use the part you wanted to import.

MEF will simply reject the request for the Import of a part for a number of reasons.  For example, if there is no part defined as the correct Export contract type.  Say you wanted to import IUserService, but only exported UserService with [Export] and no contract type of IUserService was defined.  That was the typical one I found myself forgetting to do.  As recommended above, always include the Contract Type when designated a part as Export with [Export(typeof(IUserService))].

I agree that MEF’s Rejection policy is a power feature because it stabilizes the code and allows debugging.  Glenn links to a good article on why to ensure application stability: http://blogs.msdn.com/gblock/archive/2009/08/02/stable-composition-in-mef-preview-6.aspx

But in short, if you get Rejection happening quite often, check your Export contract definition on your part.

In Summary

As you can see, it is dead simple to use MEF.  The Export functionality is what was missing with Unity, and completely with all other IoC containers.  And, it’s what gives MEF such great, simplistic power.  I highly recommend reading through Glenn’s complete article, as he covers a few other concepts such as using the new Lazy<T> for importing lazy exports and metadata.

Some additional things Glenn covers is the very strong support for debugging and tracing, things you want to be aware of if you use MEF even moderately.  He also hints at the up-n-coming support for MEF with IronRuby.  He also covers some external links, which I will list here (for my own archiving purposes):

Once concept I am tinkering with is utilizing the [Import] attribute in the attributed programming model of MEF to define the complete contexts of my BDD tests for me with all dependencies already mocked up and ready, with T4 templates largely driving that effort.

MEF wacked me upside the head.  It does everything right, and even allowed me to step back and realized, “Dang. I was bloating my code.”  Yes, they have done it right.  So right that the next project I am starting this week will be on Visual Studio 2010 RC – not even released yet. 

> Revision History
> About the author