A Simple Introduction to the Managed Extensibility Framework

It is very common for us developers to spend more time modifying existing applications than building new ones from the scratch. New business requirements usually need new features in software applications. Nowadays, the way those requirements are usually added ends when we generate, test, and deploy a new version of the application. Those activities very often affect the entire application, not only the new features added.

When requirements change, we developers should change the corresponding features in the application. After years and years of evolution, source code implementing those features typically has undesired dependencies, and modifications can turn the application unstable, or demand extensive regression testing to make sure new bugs has not been introduced. Also in this case the story ends when we generate and deploy the entire application again.

These days businesses change more, and more often, to survive in a globalized and competitive world. And the software applications that makes those businesses work should also change, and change faster.

Let’s suppose for a moment that every single functionality of an application can be decomposed into a “part”. What we need is the ability to develop weakly coupled parts; independent not only in its structure, but also in its testing, and deployment; and also that those parts can be easily composed into an application.

Software engineering principles required to solve this situation have been known for a long time, and many organizations apply them successfully. But those solutions are usually on case by case basis, and are not available to the general public like us.

Recently, some software development frameworks have appeared to develop applications in parts. MEF is one of them.

There are the following roles in MEF:

Exported parts. They declare that they can be used to compose an application and the contract they implement. They are independent development, compilation, and deployment units. They are weakly coupled, not only with other parts in the application they will compose, but also with the application itself, i.e., a part does not know other parts, and does not know necessarily in which application it will be used.

Import points. They are variables that contain parts or collections of imported parts that must implement a specific contract. Parts are automatically created from the information contained in parts catalogs.

Parts catalogs. They contain parts definitions: where they are and what contract they implement.

Parts containers. They contain parts instances and they perform composition of parts.

I will show you how to develop a MEF application step by step. To understand MEF the application must be simple, but must offer multiple features decomposable in parts.

The application in this example allows writing some text and then transforming it by applying different algorithms. Each algorithm offers different functionality and that is what I will transform into parts. The application looks like this:

The drop down list shows available transformations:

The goal is to develop the user interface and each transformation independent for each other. There we go.

We declare the contract that parts must implement with the IFilter interface as follows:

public interface IFilter
{
string Filter(string input);
}

Then we create a part (the transformation ToUnicodeFilter for example) implementing the IFilter interface and we declare it as exportable with the MEF attribute Export:

The transformation in this case is to convert each character of the input text into its correspondent Unicode representation.

We can have as much parts as we want, but all of them must implement the IFilter interface and be decorated with the Export attribute.

Let’s start coding the composition of parts into the application. We need a catalog to describe our parts. In this example all assemblies containing parts will be in a folder called Extensions, so we use a DirectoryCatalog:

DirectoryCatalog catalog = new DirectoryCatalog(“Extensions”);

We also need a container for the part instances and to build the composition. The container receives the catalog as parameter, so it can know where to find the parts:

CompositionContainer container = new CompositionContainer(catalog);

We are almost there. What we need now is a point where to import the parts. In this case there can be many transformations, so we declare an IList<IFilter> that we decorate with the ImportMany attribute.

Three assemblies are playing here. The first one is where the IFilter interface is declared. The second one is where the class ToUnicodeFilter is declared. The third one is the application itself. The interesting thing here is that in order to add another transformation or to modify an existing one, the only thing we need to do is to deploy the assembly to the Extensions folder. Other assemblies are not affected, including the application assembly.

How this magic works? When the ComposeParts method of the container is called, passing the application itself as parameter, the container looks for all variables decorated with the ImportMany (or with the Import) attribute. In each case the interface required by the import point is also found by the container.

The container knows the catalog, because we passed it as parameter to the constructor. Since the catalog has the information of all parts, including which parts implements which interface, it can find which part or parts implement the interface of each import point. As the catalog also knows where the assemblies implementing the parts are, it can create instances of the appropriate part or parts, and assign them to the variables corresponding to the import points.

Finally, the composition “is built alone”, the work is done by MEF, not by the developer. The developer only “decorates” the types with Export, variables with Import or ImportMany, creates one or more catalogs and the container, and finally composes the parts. It is simple, is not it?

Remember that the challenge was to develop weakly coupled parts, independent not only on its structure, but also in deployment; and that those parts could be easily composed into an application. Goal achieved? I think so.

You can download the code for this sample application from here. The sample contains even more parts than the ones I am showing here.

6 Responses

[…] leave a comment » Inversion of Control and Dependency Injection are a sort of buzz words, in the sense that when you dig into their definitions, they do not necessarily means exactly the same thing to different people. Recently I engaged in a discussion with my good friend Leon Welicki from Microsoft’s WCF team, around the simple question is the Managed Extensibility Framework an Inversion of Control/Dependency Injection framework? I will try to answer this question. If you are new to MEF, you can read an introduction in this previous post. […]

[…] using the class I created to accomplish the task as example (by the way, I might have used the Managed Extensibility Framework to load the types, but in such case I had not been able to write this […]

[…] Giving a Presentation is a WPF application sample created in C# that I use when blogging about Managed Extensibility Framework, Dependency Injection and Inversion of Control, etc. It demonstrates how an extensible application […]

[…] Inversion of Control and Dependency Injection are a sort of buzz words, in the sense that when you dig into their definitions, they do not necessarily means exactly the same thing to different people. Recently I engaged in a discussion with my good friend Leon Welicki from Microsoft’s WF team, around the simple question is the Managed Extensibility Framework an Inversion of Control/Dependency Injection framework? I will try to answer this question. If you are new to MEF, you can read an introduction in this previous post. […]