Definition from MSDN:
The Managed Extensibility Framework or MEF is a library for creating
lightweight, extensible applications. It allows application developers to
discover and use extensions with no configuration required. It also lets
extension developers easily encapsulate code and avoid fragile hard
dependencies. MEF not only allows extensions to be reused within applications,
but across applications as well.
Instead of this explicit registration of available components, MEF provides a
way to discover them implicitly, via composition. A
MEF component, called a part, declaratively
specifies both its dependencies (known as imports)
and what capabilities (known as exports) it makes
available. When a part is created, the MEF composition engine satisfies its
imports with what is available from other parts.
This approach solves the problems discussed in the previous section. Because MEF parts declaratively specify their capabilities, they are discoverable at runtime, which means an application can make use of parts without either hard-coded references or fragile configuration files. MEF allows applications to discover and examine parts by their metadata, without instantiating them or even loading their assemblies. As a result, there is no need to carefully specify when and how extensions should be loaded.
In addition to its provided exports, a part can specify its imports, which will be filled by other parts. This makes communication among parts not only possible, but easy, and allows for good factoring of code. For example, services common to many components can be factored into a separate part and easily modified or replaced.
Because the MEF model requires no hard dependency on a particular application assembly, it allows extensions to be reused from application to application. This also makes it easy to develop a test harness, independent of the application, to test extension components.
An extensible application written by using MEF declares an import that can be filled by extension components, and may also declare exports in order to expose application services to extensions. Each extension component declares an export, and may also declare imports. In this way, extension components themselves are automatically extensible.
SharedContracts (for our interfaces)
CalculatorService1 (plug-in)
CalculatorService2 (plug-in).
The Console Application and SharedContracts projects will need to reference MEF and the our Interfaces so right clcik and add the two references for each project.
MEF is stored within the System.ComponentModel.Composition framework (System.ComponentModel.Composition.DLL).
In our example the plug-ins will be loaded from a known directory location. In production you would load this location from a config but for this demo we’ll be hardcoding the location (@”../plugins” folder) in the host and building the output of the plug-ins to the same folder. To alter the output right click on view properties on both plugins click the “Build” tab and update the “Output Path”:
NOTE: Notice the (MEF) InheritedExport attribute on the interface,
this allows MEF to discover the class within the plugin.
Remove the default Class1.cs file, add a file called Addition.cs and paste in the following code:
Finally replace the text in the Program.cs file with the following code:
Your solution should now look like this, notice I’ve removed all redundant references from each of the projects:

You are now ready to run the application, press F5 and check out your results:
You can download the source code here:
http://stevenhollidge.com/blog-source-code/MefSimpleDemo.zip
This approach solves the problems discussed in the previous section. Because MEF parts declaratively specify their capabilities, they are discoverable at runtime, which means an application can make use of parts without either hard-coded references or fragile configuration files. MEF allows applications to discover and examine parts by their metadata, without instantiating them or even loading their assemblies. As a result, there is no need to carefully specify when and how extensions should be loaded.
In addition to its provided exports, a part can specify its imports, which will be filled by other parts. This makes communication among parts not only possible, but easy, and allows for good factoring of code. For example, services common to many components can be factored into a separate part and easily modified or replaced.
Because the MEF model requires no hard dependency on a particular application assembly, it allows extensions to be reused from application to application. This also makes it easy to develop a test harness, independent of the application, to test extension components.
An extensible application written by using MEF declares an import that can be filled by extension components, and may also declare exports in order to expose application services to extensions. Each extension component declares an export, and may also declare imports. In this way, extension components themselves are automatically extensible.
Architecture:

To bootstrap, MEF involves a few steps:

Figure 1 Core Concepts in the Managed Extensibility Framework
A simple example:
http://stevenhollidge.blogspot.sg/2011/04/how-to-use-mef-with-c.html
(see explanation below)
The above part exports the SalesOrderView contract. By
default, the Export attribute uses the concrete type of the member (in
this case, the class) as the contract. You can also explicitly specify
the contract by passing a parameter to the attribute’s constructor.
In general, importing via constructors rather than properties
is a matter of preference, though there are times when it’s appropriate
to use property imports, particularly when there are parts that aren’t
instantiated by MEF, as in the WPF App example. Recomposition is also
not supported on constructor parameters.
To bootstrap MEF involves a few steps:
During composition, the container will create the ViewFactory
and satisfy its SalesOrderView import. This will result in
SalesOrderView being created. Finally, the Application class will have
its ViewFactory import satisfied. In this way, MEF has assembled the
entire object graph based on declarative information, rather than
manually requiring imperative code to do the assembly.
To support this, MEF allows property exports. To use property exports, you create an intermediary part with a property that is decorated with an export. That property is essentially a factory and executes whatever custom logic is necessary to retrieve the non-MEF value. In the following code sample, you can see that Loggerpart exports a Log4Net logger, allowing other parts such as the App to import it rather than depending on accessing the static accessor method:
Property exports are like Swiss Army knives in their
functionality, allowing MEF to play well with others. You will find them
extremely useful for integrating MEF into your existing apps and for
talking to legacy systems.
In the preceding code, I changed SalesOrderView to implement
ISalesOrderView and explicitly export it. I also changed the factory on
the importer side to import ISalesOrderView. Notice the importer doesn’t
have to specify the type explicitly, as MEF can derive it from the
property type, which is ISalesOrderView.
This raises the question of whether ViewFactory should also implement an interface like IViewFactory. This isn’t a requirement, though it may make sense for mocking purposes. In this case I’m not expecting anyone to replace ViewFactory, and it’s designed in a testable fashion, so it’s fine. You can have multiple exports on a part in order to have the part imported under multiple contracts. SalesOrderView, for example, can export both UserControl and ISalesOrderView by having an additional export attribute:
If many types of views are expected, MEF offers a better approach. Instead of using a specific view interface, you can create a generic IView interface that all views export. The factory then imports a collection of all available IViews. To import a collection in the attributed model, use the ImportMany attribute:
Here you can see that ViewFactory now imports a collection of
IView instances rather than a specific view. SalesOrder implements
IView and exports it rather than ISalesOrderView. With this refactoring,
ViewFactory can now support an open set of views.
MEF also supports importing using concrete collections such as ObservableCollection or List, as well as custom
collections that provide a default constructor.
Part creation policy in MEF can be one of three values: CreationPolicy.Shared, CreationPolicy.NonShared or CreationPolicy.Any. To specify creation policy on a part, you decorate it with the partCreationPolicy attribute, as shown here:
PartCreationPolicy can also be specified on the importer side by setting the RequiredCreationPolicy property on the import.
ExportMetadata has two parameters, a key that is a string and
a value of type object. Using magic strings as in the preceding example
can be problematic because this isn’t compile-safe. Instead of a magic
string, we can supply a constant for the key and an enum for the value:
Using the ExportMetadata attribute provides a lot of flexibility, but there are several caveats when using it:
ExportViewAttribute specifies that it exports IView by
calling Export’s base constructor. It’s decorated with a
MetadataAttribute, which specifies that the attribute provides metadata.
This attribute tells MEF to look at all of the public properties and
create associated metadata on the export using the property name as the
key. In this case, the only metadata is ViewType.
The last important thing to note about the ExportView attribute is that it’s decorated with an AttributeUsage attribute. This specifies that the attribute is valid only on classes and that only a single ExportView attribute can be present.
In general, AllowMultiple should be set to false; if it’s true, the importer will be passed an array of values rather than a single value. AllowMultiple should be left as true when there are multiple exports with different metadata of the same contract on the same member.
Applying the new ExportViewAttribute to the SalesOrderView now results in the following:
As you can see, custom exports ensure the correct metadata is
provided for a particular export. They also reduce noise in the code,
are more discoverable through IntelliSense and better express intent
through being domain-specific.
Now that metadata has been defined on the view, the ViewFactory can import it.
. It allows delaying the instantiation
of an instance until the value property of the Lazy is accessed. MEF
further extends Lazy with Lazy to allow
accessing export metadata without instantiating the underlying export.
TMetadata is a metadata view type. A metadata view is an interface that defines read-only properties that correspond to keys in the exported metadata. When the metadata property is accessed, MEF will dynamically implement TMetadata and will set the values based on the provided metadata from the export.
This is how ViewFactory looks when the View property is changed to import using Lazy:
Once a collection of lazy exports with metadata has been
imported, you can use LINQ to filter against the set. In the following
code snippet, I’ve implemented a GetViews method on ViewFactory to
retrieve all views of the specified type. Notice it accesses the Value
property in order to manufacture the real view instances only for the
views that match the filter:
With these changes, ViewFactory now discovers all views that are available at the time the factory is composed by MEF.
If new implementations appear in the container or catalogs after that
initial composition, they won’t be seen by the ViewFactory, as it was
already composed. Not only that, but MEF will actually prevent the views
from being added to the catalog by throwing a CompositionException—that
is, unless recomposition is enabled.
When recomposition occurs, the Views collection will instantly
be replaced with a new collection that contains the updated set of
views.
With recomposition enabled, the app can download additional assemblies from the server and add them to the container. You can do this through MEF’s catalogs. MEF offers several catalogs, two of which are recomposable. DirectoryCatalog, which you have already seen, is one that is recomposed by calling its Refresh method. Another recomposable catalog is AggregateCatalog, which is a catalog of catalogs. You add catalogs to it by using the Catalogs collection property, which starts recomposition. The last catalog I’ll use is an AssemblyCatalog, which accepts an assembly upon which it then builds a catalog. Figure 2 shows a sample illustrating how you can use these catalogs together for dynamic download.
Figure 2 Using MEF Catalogs for Dynamic Download
The container in Figure 2 is created with
an AggregateCatalog. It then has a DirectoryCatalog added to it in order
to grab the local parts in the bin folder. The aggregate catalog is
passed to the DownloadAssemblies method, which asynchronously downloads
assemblies and then calls AddAssemblies. That method creates a new
AggregateCatalog, to which it adds AssemblyCatalogs for each download
assembly. AddAssemblies then adds the AggregateCatalog containing the
assemblies for the main aggregate. The reason it adds in this fashion is
to have recomposition occur in one shot, rather than over and over
again, which is what would happen if we added assembly catalogs
directly.
When recomposition occurs, the collection is immediately updated. Depending on the collection property type, the result is different. If the property is of type IEnumerable,
it’s replaced with a new instance. If it’s a concrete collection that
inherits from List or ICollection, then MEF will call Clear and
then Add for each item. In either case, it means you will have to
consider thread-safety when using Recomposition. Recomposition not only
relates to adds, it also relates to removals. If catalogs are removed
from the container, those parts will also be removed .
Here, SalesOrderView has been changed to import an ILogger though there’s no logger instance present:
Because there isn’t an ILogger export available,
SalesOrderView’s export won’t appear to the container. This won’t throw
an exception; instead SalesOrderView will just be ignored. If you check
ViewFactory’s Views collection, it will be empty.
Rejection will also happen in cases where there are multiple exports available for a single import. In those cases, the part that imports the single export is rejected:
In the preceding example, SalesOrderView will be rejected
because there are multiple ILogger implementations, but a single
implementation is imported. MEF does provide facilities for allowing a
default export in the presence of multiples. For more on this, see codebetter.com/blogs/glenn.block/archive/2009/05/14/customizing-container-behavior-part-2-of-n-defaults.aspx.
You might ask why MEF doesn’t create SalesOrderView and throw an exception. In an open extensible system, if MEF throws an exception, it would be very difficult for the application to handle it, or to have the context to know what to do, because the part might be missing or the import might be nested very deeply in the composition. Without proper handling, the app would be in an invalid state and unusable. MEF rejects the part, thus ensuring application stability is maintained. For more on stable composition, see: blogs.msdn.com/gblock/archive/2009/08/02/stable-composition-in-mef-preview-6.aspx.
MEF doesn’t leave you in the dark. To assist with diagnosing this problem, it provides tracing. In the IDE, all rejection messages are traced to the output window, though they can also be traced to any valid trace listener. For example, when the app attempts to import MainWindow, the trace messages in Figure 3 will be outputted.
Figure 3 MEF Trace Messages
The trace output shows the root cause of the problem:
SalesOrderView requires an ILogger and one cannot be located. We can
then see that rejecting it caused the factory to be rejected, and
ultimately the MainWindow.

Figure 4 Available Parts and Required ILogger Shown in a Watch Window
If you run MEFX.exe at the command line, you will see a host of options; you can list specific imports, exports or all parts available. For example, here you can see using MEFX to display the list of parts:
This is useful for getting a part inventory, but MEFX can also track down rejections, which is our interest here, as shown in Figure 5.
Figure 5 Tracking Down Rejections with MEFX.exe
Dissecting the output in Figure 5 reveals the
root cause of the problem: ILogger can’t be located. As you can see, in
large systems with many parts, MEFX is an invaluable tool. For more on
MEFX, see blogs.msdn.com/nblumhardt/archive/2009/08/28/analyze-mef-assemblies-from-the-command-line.aspx.
Summarizing, there are several advantages of the attributed model:

Figure 6 A Part Example in IronRuby
MEF does not ship with an IronRuby programming model, though it’s likely we will add dynamic language support in the future.
You can read more about experiments in building a Ruby programming model in this blog series: blogs.msdn.com/nblumhardt/archive/tags/Ruby/default.aspx.
Catalogs provide part definitions (ComposablepartDefinition), which describe the available exports and imports. They are the main unit for discovery in MEF. MEF provides several catalogs in the System.ComponentModel.Composition namespace, some of which you already saw, including DirectoryCatalog, which scans a directory; AssemblyCatalog, which scans an assembly; and TypeCatalog, which scans through a specific set of types. Each of these catalogs is specific to the attributed programming model. The AggregateCatalog, however, is agnostic to programming models. Catalogs inherit from ComposablepartCatalog and are an extensibility point in MEF. Custom catalogs have several uses, from providing a completely new programming model to wrapping and filtering existing catalogs.
Figure 7 shows an example of a filtered catalog, which accepts a predicate to filter against the inner catalog from which parts will be returned.
Figure 7 A Filtered Catalog
The CompositionContainer composes, meaning it creates parts
and satisfies imports of those parts. In satisfying the imports, it will
grab from the pool of available exports. If those exports also have
imports, the container will satisfy them first. In this way, the
container assembles entire object graphs on demand. The primary source
for the pool of exports is a catalog, but the container can also have
existing part instances directly added to it and composed. It’s
customary to manually add the entry point class to the container,
combined with parts pulled from the catalog, though in most cases parts
will come from the catalog.
Containers can also be nested in a hierarchy in order to support scoping scenarios. Child containers by default will query the parent, but they can also provide their own catalogs of child parts, which will be created within the child container:
In the preceding code, childContainer is arranged as a child
of rootContainer. Both rootContainer and childContainer provide their
own catalogs. For more on using the container to host MEF within your
applications, see http://codebetter.com/glennblock/2009/11/29/mef-has-landed-in-silverlight-4-we-come-in-the-name-of-extensibility/.
Exploring the primitives is a journey of its own, and one I’ll likely take in a future article. For now, you can find out more about it at blogs.msdn.com/dsplaisted/archive/2009/06/08/a-crash-course-on-the-mef-primitives.aspx.
You can find out more about MEF in Silverlight 4 in this post: http://codebetter.com/glennblock/2009/11/29/mef-has-landed-in-silverlight-4-we-come-in-the-name-of-extensibility/.
I’ve just scratched the surface of what you can do with MEF. It’s a powerful, robust and flexible tool that you can add to your arsenal to help open up your applications to a whole new world of possibilities. I look forward to seeing what you do with it!
To bootstrap, MEF involves a few steps:
- Add imports of the contracts you need the container to create, which i explained in the above section.
- Create a catalog that MEF uses to discover parts.
- Create a container that composes instances of parts.
- Compose by calling the Composeparts method on the container and passing in the instance that has the imports.

Figure 1 Core Concepts in the Managed Extensibility Framework
A simple example:
http://stevenhollidge.blogspot.sg/2011/04/how-to-use-mef-with-c.html
(see explanation below)
Walkthrough of a MEF example from MSDN
Programming Models—the Face(s) of MEF
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.Diving into the Attributed Programming Model
In the attributed programming model, parts (known as attributed parts) are defined with a set of .NET attributes, which live in the System.ComponentModel.Composition namespace. In the sections that follow, I’ll explore building an extensible Windows Presentation Foundation (WPF) sales order management application using this model. This application allows customers to add new, customized views within their environments simply by deploying a binary to the bin folder. I’ll look at how this can be implemented through MEF. I’ll incrementally improve the design as I go, and explain more about MEF’s capabilities and what the attributed programming model provides in the process.Exporting a Class
The order management application allows plugging in new views. To export something to MEF, you export it by using the Export attribute as shown here:[Export]
public partial class SalesOrderView : UserControl
{
public SalesOrderView()
{
InitializeComponent();
}
}
Importing Through Properties and Fields
Attributed parts can express the things they need by using the import attribute on a property or field. The application exports a ViewFactory part, which other parts can use to get to views. That ViewFactory imports SalesOrderView using a property import. Importing a property simply means decorating a property with an Import attribute:[Export]
public class ViewFactory
{
[Import]
public SalesOrderView OrderView { get; set; }
}
Importing Through Constructors
Parts can also import through constructors (commonly known as constructor injection) by using the ImportingConstructor attribute as shown below. When using an importing constructor, MEF assumes all parameters are imports, making the import attribute unnecessary:[Export]
public class ViewFactory
{
[ImportingConstructor]
public ViewFactory(SalesOrderView salesOrderView)
{
}
}
Composition
With SalesOrderView and ViewFactory in place, you can now start composition. MEF parts don’t automatically get discovered or created. Instead, you need to write some bootstrapping code that will enact composition. A common place to do this is in your application’s entry point, which in this case is the App class.To bootstrap MEF involves a few steps:
- Add imports of the contracts you need the container to create.
- Create a catalog that MEF uses to discover parts.
- Create a container that composes instances of parts.
- Compose by calling the Composeparts method on the container and passing in the instance that has the imports.
public partial class App : Application
{
[Import]
public ViewFactory ViewFactory { get; set; }
public App()
{
this.Startup += new StartupEventHandler(App_Startup);
}
void App_Startup(object sender, StartupEventArgs e)
{
var catalog = new DirectoryCatalog(@".\");
var container = new CompositionContainer(catalog);
container.Composeparts(this);
}
}
Exporting Non-MEF Items to MEF Through Properties
When integrating MEF into an existing application, or with other frameworks, you will often find non-MEF related class instances (meaning they are not parts) that you will want to make available to importers. These may be sealed framework types such as System.String; application-wide singletons such as Application.Current; or instances retrieved from a factory, such as a logger instance retrieved from Log4Net.To support this, MEF allows property exports. To use property exports, you create an intermediary part with a property that is decorated with an export. That property is essentially a factory and executes whatever custom logic is necessary to retrieve the non-MEF value. In the following code sample, you can see that Loggerpart exports a Log4Net logger, allowing other parts such as the App to import it rather than depending on accessing the static accessor method:
public class Loggerpart
{
[Export]
public ILog Logger
{
get { return LogManager.GetLogger("Logger"); }
}
}
Decoupling Implementation with an Interface
Going back to the SalesOrderView example, a tightly coupled relationship has been formed between ViewFactory and SalesOrderView. The factory expects a concrete SalesOrderView that limits extensibility options as well as testability of the factory itself. MEF allows imports to be decoupled from the exporter’s implementation by using an interface as the contract:public interface ISalesOrderView{}
[Export(typeof(ISalesOrderView))]
public partial class SalesOrderView : UserControl, ISalesOrderView
{
...
}
[Export]
public class ViewFactory
{
[Import]
ISalesOrderView OrderView{ get; set; }
}
This raises the question of whether ViewFactory should also implement an interface like IViewFactory. This isn’t a requirement, though it may make sense for mocking purposes. In this case I’m not expecting anyone to replace ViewFactory, and it’s designed in a testable fashion, so it’s fine. You can have multiple exports on a part in order to have the part imported under multiple contracts. SalesOrderView, for example, can export both UserControl and ISalesOrderView by having an additional export attribute:
[Export (typeof(ISalesOrderView))]
[Export (typeof(UserControl))]
public partial class SalesOrderView : UserControl, ISalesOrderView
{
...
}
Contract Assemblies
As you start to create contracts, you will need a way to deploy those contracts to third parties. A common way to do this is by having a contract assembly that contains interfaces for the contracts that will be implemented by extenders. The contract assembly becomes a form of SDK that the parts will reference. A common pattern is to name the contract assembly as the application name + .Contracts, such as SalesOrderManager.Contracts.Importing Many Exports of the Same Contract
Currently ViewFactory imports only a single view. Hardcoding a member (property param) for each view works for a very small number of predefined types of views that aren’t changing frequently. However, with such an approach, adding new views requires the factory to be recompiled.If many types of views are expected, MEF offers a better approach. Instead of using a specific view interface, you can create a generic IView interface that all views export. The factory then imports a collection of all available IViews. To import a collection in the attributed model, use the ImportMany attribute:
[Export]
public class ViewFactory
{
[ImportMany]
IEnumerable Views { get; set; }
}
[Export(typeof(IView))]
public partial class SalesOrderView : UserControl, IView
{
}
//in a contract assembly
public interface IView{}
MEF also supports importing using concrete collections such as ObservableCollection
Controlling Part Creation Policy
By default, all part instances in the container are singletons, thus they are shared by any parts that import them within the container. For this reason, all importers of SalesOrderView and ViewFactory will get the same instance. In many cases this is desirable, as it replaces having static members that other components depend on. However, sometimes it’s necessary for each importer to get its own instance, for example, to allow multiple SalesOrderView instances to be viewed on the screen at the same time.Part creation policy in MEF can be one of three values: CreationPolicy.Shared, CreationPolicy.NonShared or CreationPolicy.Any. To specify creation policy on a part, you decorate it with the partCreationPolicy attribute, as shown here:
[partCreationPolicy(CreationPolicy.NonShared)]
[Export(typeof(ISalesOrderView))]
public partial class SalesOrderView : UserControl, ISalesOrdderView
{
public SalesOrderView()
{
}
}
Distinguishing Exports with Metadata
ViewFactory now works with an open set of views, but I have no way to distinguish one view from another. I could add a member to IView called ViewType, which the view would provide, and then filter against that property. An alternative is to use MEF’s export metadata facilities to annotate the view with its ViewType. Using the metadata provides an additional advantage of allowing the view’s instantiation to be delayed until it’s needed, which can conserve resources and improve performance.Defining Export Metadata
To define metadata on an export, you use the ExportMetadata attribute. Below, SalesOrderView has been changed to export an IView marker interface as its contract. It then adds additional metadata of “ViewType” so that it can be located among other views that share the same contract:[ExportMetadata("ViewType", "SalesOrder")]
[Export(typeof(IView)]
public partial class SalesOrderView : UserControl, IView
{
}
[ExportMetadata(ViewMetadata.ViewType, ViewTypes.SalesOrder)]
[Export(typeof(IView)]
public partial class SalesOrderView : UserControl, IView
{
...
}
//in a contract assembly
public enum ViewTypes {SalesOrderView}
public class ViewMetadata
{
public const string ViewType = "ViewType";
}
- Metadata keys aren’t discoverable in the IDE. The part author must know which metadata keys and types are valid for the export.
- The compiler won’t validate metadata to ensure it’s correct.
- ExportMetadata adds more noise to the code, hiding the intent.
Custom Export Attributes
MEF allows the creation of custom exports that include their own metadata. Creating a custom export involves creating a derived ExportAttribute that also specifies metadata. We can use custom exports to create an ExportView attribute that includes metadata for ViewType:[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class ExportViewAttribute : ExportAttribute {
public ExportViewAttribute()
:base(typeof(IView))
{}
public ViewTypes ViewType { get; set; }
}
The last important thing to note about the ExportView attribute is that it’s decorated with an AttributeUsage attribute. This specifies that the attribute is valid only on classes and that only a single ExportView attribute can be present.
In general, AllowMultiple should be set to false; if it’s true, the importer will be passed an array of values rather than a single value. AllowMultiple should be left as true when there are multiple exports with different metadata of the same contract on the same member.
Applying the new ExportViewAttribute to the SalesOrderView now results in the following:
[ExportView(ViewType = ViewTypes.SalesOrder)]
public partial class SalesOrderView : UserControl, IView
{
}
Now that metadata has been defined on the view, the ViewFactory can import it.
Importing Lazy Exports and Accessing Metadata
To allow the accessing of metadata, MEF leverages a new API of the .NET Framework 4, System.LazyTMetadata is a metadata view type. A metadata view is an interface that defines read-only properties that correspond to keys in the exported metadata. When the metadata property is accessed, MEF will dynamically implement TMetadata and will set the values based on the provided metadata from the export.
This is how ViewFactory looks when the View property is changed to import using Lazy
[Export]
public class ViewFactory
{
[ImportMany]
IEnumerable> Views { get; set; }
}
public interface IViewMetadata
{
ViewTypes ViewType {get;}
}
[Export]
public class ViewFactory
{
[ImportMany]
IEnumerable> Views { get; set; }
public IEnumerable GetViews(ViewTypesviewType) {
return Views.Where(v=>v.Metadata.ViewType.Equals(viewType)).Select(v=>v.Value);
}
}
Recomposition
Recomposition is a feature of MEF that allows parts to automatically have their imports updated as new matching exports appear in the system. One scenario where recomposition is useful is for downloading parts from a remote server. SalesOrderManager can be changed so that when it starts up, it initiates a download for several optional views. As the views show up, they will appear in the view factory. To make the ViewFactory recomposable, we set the AllowRecomposition property on the ImportMany attribute of the Views property to true, as shown here:[Export]
public class ViewFactory
{
[ImportMany(AllowRecomposition=true)]
IEnumerable> Views { get; set; }
public IEnumerableGetViews(ViewTypesviewType) {
return Views.Where(v=>v.Metadata.ViewType.Equals(viewType)).Select(v=>v.Value);
}
}
With recomposition enabled, the app can download additional assemblies from the server and add them to the container. You can do this through MEF’s catalogs. MEF offers several catalogs, two of which are recomposable. DirectoryCatalog, which you have already seen, is one that is recomposed by calling its Refresh method. Another recomposable catalog is AggregateCatalog, which is a catalog of catalogs. You add catalogs to it by using the Catalogs collection property, which starts recomposition. The last catalog I’ll use is an AssemblyCatalog, which accepts an assembly upon which it then builds a catalog. Figure 2 shows a sample illustrating how you can use these catalogs together for dynamic download.
Figure 2 Using MEF Catalogs for Dynamic Download
void App_Startup(object sender, StartupEventArgs e)
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(newDirectoryCatalog((@"\.")));
var container = new CompositionContainer(catalog);
container.Composeparts(this);
base.MainWindow = MainWindow;
this.DownloadAssemblies(catalog);
}
private void DownloadAssemblies(AggregateCatalog catalog)
{
//asynchronously downloads assemblies and calls AddAssemblies
}
private void AddAssemblies(Assembly[] assemblies, AggregateCatalog catalog)
{
var assemblyCatalogs = new AggregateCatalog();
foreach(Assembly assembly in assemblies)
assemblyCatalogs.Catalogs.Add(new AssemblyCatalog(assembly));
catalog.Catalogs.Add(assemblyCatalogs);
}
When recomposition occurs, the collection is immediately updated. Depending on the collection property type, the result is different. If the property is of type IEnumerable
Stable Composition, Rejection and Diagnostics
Sometimes a part may specify an import that is missing, as it isn’t present in the catalog. When this happens, MEF prevents the part missing the dependency—or anything that depends on it—from being discovered. MEF does this in order to stabilize the system and prevent runtime failures that would surely occur if the part were created.Here, SalesOrderView has been changed to import an ILogger though there’s no logger instance present:
[ExportView(ViewType = ViewTypes.SalesOrder)]
public partial class SalesOrderView : UserControl, IView
{
[Import]
public ILogger Logger { get; set; }
}
Rejection will also happen in cases where there are multiple exports available for a single import. In those cases, the part that imports the single export is rejected:
[ExportView(ViewType = ViewTypes.SalesOrder)]
public partial class SalesOrderView : UserControl, IView
{
[Import]
public ILogger Logger { get; set; }
}
[Export(typeof(ILogger))]
public partial class Logger1 : ILogger
{
}
[Export(typeof(ILogger))]
public partial class Logger2 : ILogger
{
}
You might ask why MEF doesn’t create SalesOrderView and throw an exception. In an open extensible system, if MEF throws an exception, it would be very difficult for the application to handle it, or to have the context to know what to do, because the part might be missing or the import might be nested very deeply in the composition. Without proper handling, the app would be in an invalid state and unusable. MEF rejects the part, thus ensuring application stability is maintained. For more on stable composition, see: blogs.msdn.com/gblock/archive/2009/08/02/stable-composition-in-mef-preview-6.aspx.
Diagnosing Rejection
Rejection is a very powerful feature, but it can sometimes be difficult to diagnose, especially when the entire dependency graph is rejected. In the first early example, ViewFactory directly imports a SalesOrderView. Let’s say MainWindow imported ViewFactory and SalesOrderView is rejected. Then ViewFactory and MainWindow will also get rejected. You might be scratching your head if you see this occur, as you know that MainWindow and ViewFactory actually are present; the reason for the rejection is a missing dependency.MEF doesn’t leave you in the dark. To assist with diagnosing this problem, it provides tracing. In the IDE, all rejection messages are traced to the output window, though they can also be traced to any valid trace listener. For example, when the app attempts to import MainWindow, the trace messages in Figure 3 will be outputted.
Figure 3 MEF Trace Messages
System.ComponentModel.Composition Warning: 1 : The ComposablepartDefinition 'Mef_MSDN_Article.SalesOrderView' has been rejected. The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.
1) No valid exports were found that match the constraint '((exportDefinition.ContractName == "Mef_MSDN_Article.ILogger") AndAlso (exportDefini-tion.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "Mef_MSDN_Article.ILogger".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.
Resulting in: Cannot set import 'Mef_MSDN_Article.SalesOrderView.Logger (ContractName="Mef_MSDN_Article.ILogger")' on part 'Mef_MSDN_Article.SalesOrderView'.
Element: Mef_MSDN_Article.SalesOrderView.logger (ContractName="Mef_MSDN_Article.ILogger") -->Mef_MSDN_Article.SalesOrderView -->TypeCatalog (Types='Mef_MSDN_Article.MainWindow, Mef_MSDN_Article.SalesOrderView, ...').
Inspecting Parts in the Debugger
You can go one step further and actually inspect the available parts in the catalog, which I’ll discuss in the section on hosting. In Figure 4 you can see in the watch window the available parts (in the green circles) as well as the required ILogger import (in the blue circle).
Figure 4 Available Parts and Required ILogger Shown in a Watch Window
Diagnosing Rejection at the Command Line
One of the goals of MEF was to support static analyzability, thus allowing composition to be analyzed outside of the runtime environment. We don’t yet have such tooling support in Visual Studio, however Nicholas Blumhardt authored MEFX.exe (mef.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=33536), a command-line tool that does the trick. MEFX analyzes assemblies and determines which parts are being rejected and why.If you run MEFX.exe at the command line, you will see a host of options; you can list specific imports, exports or all parts available. For example, here you can see using MEFX to display the list of parts:
C:\mefx>mefx.exe /dir:C:\SalesOrderManagement\bin\debug /parts
SalesOrderManagement.SalesOrderView
SalesOrderManagement.ViewFactory
SalesOrderManagement.MainWindow
Figure 5 Tracking Down Rejections with MEFX.exe
C:\mefx>mefx.exe /dir:C:\SalesOrderManagement\bin\debug /rejected /verbose
[part] SalesOrderManagement.SalesOrderView from: DirectoryCatalog (Path="C:\SalesOrderManagement\bin\debug")
[Primary Rejection]
[Export] SalesOrderManagement.SalesOrderView (ContractName="SalesOrderManagement.IView")
[Export] SalesOrderManagement.SalesOrderView (ContractName="SalesOrderManagement.IView")
[Import] SalesOrderManagement.SalesOrderView.logger (ContractName="SalesOrderManagement.ILogger")
[Exception] System.ComponentModel.Composition.ImportCardinalityMismatchException: No valid exports were found that match the constraint '((exportDefinition.ContractName == "SalesOrderManagement.ILogger") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "SalesOrderManagement.ILogger".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected.
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicCompositionatomicComposition)
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition)
at Microsoft.ComponentModel.Composition.Diagnostics.CompositionInfo.AnalyzeImportDefinition(ExportProvider host, IEnumerable`1 availableparts, ImportDefinition id)
Summarizing, there are several advantages of the attributed model:
- It provides a universal way for parts to declare their exports and imports.
- It allows systems to dynamically discover available parts rather than requiring preregistration.
- It’s statically analyzable, allowing tools like MEFX to determine failures ahead of time.
Programming Models Revisited
The attributed model is simply one implementation of those primitives that uses attributes as the means of discovery. The primitives can represent non-attributed parts or even parts that aren’t statically typed, as in the Dynamic Language Runtime (DLR). In Figure 6 you can see an IronRuby part that exports an IOperation. Notice that it uses IronRuby’s native syntax for declaring a part rather than the attributed model, as attributes aren’t supported in the DLR.
Figure 6 A Part Example in IronRuby
MEF does not ship with an IronRuby programming model, though it’s likely we will add dynamic language support in the future.
You can read more about experiments in building a Ruby programming model in this blog series: blogs.msdn.com/nblumhardt/archive/tags/Ruby/default.aspx.
Hosting: Where Composition Happens
Programming models define parts, imports and exports. In order to actually create instances and object graphs, MEF provides hosting APIs that are primarily located in the System.ComponentModel.Composition.Hosting namespace. The hosting layer offers a lot of flexibility, configurability and extensibility. It’s the place where much of the “work” in MEF is done and where discovery in MEF begins. Most folks who are simply authoring parts will never touch this namespace. If you are a hoster, however, you’ll be using them as I did earlier in order to bootstrap composition.Catalogs provide part definitions (ComposablepartDefinition), which describe the available exports and imports. They are the main unit for discovery in MEF. MEF provides several catalogs in the System.ComponentModel.Composition namespace, some of which you already saw, including DirectoryCatalog, which scans a directory; AssemblyCatalog, which scans an assembly; and TypeCatalog, which scans through a specific set of types. Each of these catalogs is specific to the attributed programming model. The AggregateCatalog, however, is agnostic to programming models. Catalogs inherit from ComposablepartCatalog and are an extensibility point in MEF. Custom catalogs have several uses, from providing a completely new programming model to wrapping and filtering existing catalogs.
Figure 7 shows an example of a filtered catalog, which accepts a predicate to filter against the inner catalog from which parts will be returned.
Figure 7 A Filtered Catalog
public class FilteredCatalog : ComposablepartCatalog,
{
private readonly composablepartcatalog _inner;
private readonly IQueryable _partsQuery;
public FilteredCatalog(ComposablepartCatalog inner,
Expression> expression)
{
_inner = inner;
_partsQuery = inner.parts.Where(expression);
}
public override IQueryable parts
{
get
{
return _partsQuery;
}
}
}
Containers can also be nested in a hierarchy in order to support scoping scenarios. Child containers by default will query the parent, but they can also provide their own catalogs of child parts, which will be created within the child container:
var catalog = new DirectoryCatalog(@".\");
var childCatalog = new DirectoryCatalog(@".\Child\";
var rootContainer = new CompositionContainer(rootCatalog));
var childContainer = new CompositionContainer(childCatalog,
rootContainer);
The Primitives: Where Parts and Programming Models Are Born
The primitives located at System.ComponentModel.Composition.Primitives are the lowest level in MEF. They are the quantum universe of MEF, so to speak, and its über extensibility point. Up until now, I’ve covered the attributed programming model. MEF’s container, however, isn’t at all bound to attributes; instead, it’s bound to the primitives. The primitives define an abstract representation of parts, which includes definitions such as ComposablepartDefinition, ImportDefinition and ExportDefinition, as well as Composablepart and Export, which represent actual instances.Exploring the primitives is a journey of its own, and one I’ll likely take in a future article. For now, you can find out more about it at blogs.msdn.com/dsplaisted/archive/2009/06/08/a-crash-course-on-the-mef-primitives.aspx.
MEF in Silverlight 4—and Beyond
MEF also ships as part of Silverlight 4. Everything I discussed here is relevant to developing extensible Rich Internet Applications. In Silverlight, we’ve gone even further and introduced additional APIs to ease the experience of building apps on MEF. These enhancements will eventually be rolled into the .NET Framework.You can find out more about MEF in Silverlight 4 in this post: http://codebetter.com/glennblock/2009/11/29/mef-has-landed-in-silverlight-4-we-come-in-the-name-of-extensibility/.
I’ve just scratched the surface of what you can do with MEF. It’s a powerful, robust and flexible tool that you can add to your arsenal to help open up your applications to a whole new world of possibilities. I look forward to seeing what you do with it!
Coding the Demo
First create a Console application called MefSimpleDemo.exe then add three class libraries to the solution:SharedContracts (for our interfaces)
CalculatorService1 (plug-in)
CalculatorService2 (plug-in).
The Console Application and SharedContracts projects will need to reference MEF and the our Interfaces so right clcik and add the two references for each project.
MEF is stored within the System.ComponentModel.Composition framework (System.ComponentModel.Composition.DLL).
In our example the plug-ins will be loaded from a known directory location. In production you would load this location from a config but for this demo we’ll be hardcoding the location (@”../plugins” folder) in the host and building the output of the plug-ins to the same folder. To alter the output right click on view properties on both plugins click the “Build” tab and update the “Output Path”:
SharedContracts.DLL Class Library
Remove the default Class1.cs file, add a file called ICalculationService.cs and paste in the following code:1 2 3 4 5 6 7 8 9 10 |
typeof(ICalculationService))] public interface ICalculationService { ; } }{ [InheritedExport( |
Pastie #2627148 linked directly from Pastie.
CalculationService1.DLL Class Library
Remove the default Class1.cs file, add a file called Addition.cs and paste in the following code:
1 2 3 4 5 6 7 8 9 10 11 12 |
return number1 + number2; } } }{ { |
Pastie #2627141 linked directly from Pastie.
CalculationService2.DLL Class Library
Remove the default Class1.cs file, add a file called Multiply.cs and paste in the following code:1 2 3 4 5 6 7 8 9 10 11 12 |
return number1 * number2; } } }{ { |
Pastie #2627143 linked directly from Pastie.
MefSimpleDemo.EXE Console Application
Add a new file called PluginRepository.cs and paste in the following code:1 2 3 4 5 6 7 8 9 10 11 12 |
"ICalculationService")] public IEnumerable{ [ImportMany( |
Pastie #1884118 linked directly from Pastie.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
try { // Production code would usually load the directory from config var catalog = new DirectoryCatalog(@"..\..\..\Plugins"); var container = new CompositionContainer(catalog); var pluginRepository = new PluginRepository() { CalculationServices = container.GetExportedValues{ { |
Pastie #1884080 linked directly from Pastie.
Your solution should now look like this, notice I’ve removed all redundant references from each of the projects:
You are now ready to run the application, press F5 and check out your results:
You can download the source code here:
http://stevenhollidge.com/blog-source-code/MefSimpleDemo.zip