Dynamic Part Instantiation in MEF

Disclaimer: This functionality is not shipping in .NET 4 (but is available in the recent CodePlex drops, see below for more details.)

The golden rule of using composition to simplify your architecture is to avoid calling the container directly.

Until now, MEF users have had to jump through hoops to observe this rule in some circumstances. The most common of these is dynamic part creation – creating instances of parts on-the-fly in response to application events.

To alleviate this, the latest Silverlight version of MEF in “Preview 7” introduces aDeclarative Context Adaptercalled PartCreator<T> .

image

PartCreator<T>

Imagine we’re writing a pluggable text editor. The application uses a part to represent the document being edited:

image Whenever the user clicks the ‘New’ button, the editor window creates a new instance:

image There are a few important things to notice here:

  • Every time OnNewDocument() executes, a new instance supporting IDocument is created (in this case the actual object will be of type TextDocument, )
  • When MEF sees an [Import] attribute on a member of type PartCreator<T> , it will use the same rules as for Lazy<T> to determine the appropriate contract,
  • The parameter T is the type of the exported value, not the type of the underlying part implementation,
  • The return value from CreatePart() is a wrapper class, PartLifetimeContext<T> , that implements IDisposable and must be used to clean up the part when it is no longer required,
  • PartLifetimeContext<T> has a property Value of type T, in this case T will be IDocument.

MEF supports PartCreator<T> implicitly, in a very similar way to Lazy<T>. There is no additional code required to get this behaviour.

PartCreator<T, TMetadata>

Many scenarios for dynamic instantiation need to select the appropriate part to instantiate from several different implementations.

In this example, imagine we’re building a simple MVC web framework (don’t confuse this with ASP.NET MVC; this is just a made-up exercise, not a serious MVC framework design.)

Developers create controllers to handle the various URLs that the web application responds to. Each controller exports the IController contract, and adds some metadata describing the route that the controller handles.

Here’s part of the controller for the /home page:

image Down in the plumbing of our MVC framework, the request handler is going to have to decide which of the available controllers will be invoked by an incoming request.

To do this, the RequestHandler part imports an array of PartCreator<IController, IControllerMetadata> .

When a request comes in (see the HandleRequest() method) the appropriate part creator is chosen and used to create a controller:

image Notice that the controller variable is used in a using block. This ensures that the controller and any other resources that were used to construct it will be cleaned up after the request is handled.

Emulating PartCreator<T> on .NET 4

PartCreator<T> is not included in the .NET 4 builds of MEF – it was developed as part of the Silverlight MEF support (where CompositionContainer is much less accessible.) However, with a little work it is possible to emulate some of the PartCreator<T> functionality.

Included with the .NET beta-compatible version of MEF is a sample that supports a limited subset of the feature, under Microsoft.ComponentModel.Composition.DynamicInstantiation.

This assembly includes versions of the part creator types, and an ExportProvider that handles requests for PartCreator<T> when added to the container.

image

This sample doesn’t fully support all container features, and (as you can tell by the lack of unit tests) may blow up in unexpected ways. Instantiation performance is also not guaranteed, thanks to O(n^2) time complexity on the number of exporters of the contract being instantiated.

We’re including this so that .NET 4 users can experiment with the part creator APIs; it is not yet recommended for production use.