DCSIMG
Using MEF - Manu Cohen-Yashar's Blog

Manu Cohen-Yashar's Blog

Using MEF

MEF – Managed extensibility framework is one of the most exciting new technologies brought by the new .Net framework 4.0.

Using MEF it is simple to create extensible applications.

There are so many extensibility design patterns but non is as simple as MEF.

One of the most popular extensibility pattern is the “provider” pattern. You define an interface that a provider should implement and in config you specify the location of the actual provider. On startup someone has to read the config, load the assembly, create an instance of the provider and start to work.

There are two main problems.

1. The configuration file gets complicated. It is filled with classes and assemblies names (Not a short definition considering the strong name and the version). The following snippet is not a rare example:

<providers>

   <add name="AspNetSqlRoleProvider"
        type="System.Web.Security.SqlRoleProvider, System.Web,
              Version=2.0.0.0, Culture=neutral,
              PublicKeyToken=b03f5f7f11d50a3a
" />       

</providers>

2. Someone has to do the job of creating the instance. There are issues to consider like: When should the provider be created? How shell the provider instance creator be available? How to insure the correct number of creations etc…

MEF provide a simple mechanism to implement the provider pattern without the manual creation of the providers. No more complex configuration. No more manual creation. MEF enables developers to create extensions dynamically, without the either the extending application or the extension requiring any specific knowledge of the other.

How to use MEF:

Step one: Define an interface the provider should implement (like good old days). Let us refer to this interface as a contract

Step two: Create one or more implementation of the interface one or many assemblies.
                 In each implementation add reference to: System.ComponentModel.Composition.

Step three: Decorate each implementation with the export attribute

[Export(typeof(IProviderContract))]
public partial class MyProvider : IProviderContract

Step four: Create the consumer. (add reference to: System.ComponentModel.Composition)

There are several ways to define the consumption. The simplest one is to create in the consumer a property of type IProviderContract that will hold the provider and decorate it with an Import attribute:

[Import]
public IProviderContract Provider { get; set; }

If you want more control on the identity of the dynamic provider you can use a CompositionContainer. This container will manage all the sources form which a provider can be created and coordinate the matching. The container needs a catalog to find all the providers.

Here is a simple example how to create a container:

var catalog = new AggregateCatalog();
var thisAssembly = new AssemblyCatalog(
                    System.Reflection.Assembly.GetExecutingAssembly());
catalog.Catalogs.Add(thisAssembly);

catalog.Catalogs.Add(new DirectoryCatalog”path”));

var container = new CompositionContainer(catalog);
          

Now when you have a container you can create a collection of all possible providers by calling: container.GetExportedObjects<IProviderContract>()

or by creating a simple property

[Import(typeof(IProviderContract))]
public ExportCollection<IProviderContract> Providers { get; set; }

This list can be queried to choose the right provider to use.

To trigger the matching between exports and imports you should call:

container.ComposeParts(all the attributed objects to be matched)

For example:
container.ComposeParts(this)

Now you are done. The consumer gets assigned a dynamically created provider ready to be used.

There is more you can do to better control the execution of MEF but this is for later posts.

Comments

No Comments

Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: