Team blog of MCS @ Middle East and Africa

This blog is created by Microsoft MEA HQ near shoring team, and it aims to share knowledge with the IT community.With its infrastructure and development sides,It brings to you the proven best practices and real world experiences from Subject Matter Experts
Follow Us On Twitter! Subscribe To Our Blog! Contact Us

Introduction to Managed Extensibility Framework

Introduction to Managed Extensibility Framework

  • Comments 1
  • Likes

Most of the applications we use now a days allows you to add more functionality to it by downloading and installing additional components that extend the already installed application. These additional components could be developed by the software vendor who developed the application, or by any other 3rd party vendor.

An example would the famous digital editing software Photoshop, where you can download and install filters that you can use later to add effects and/or enhance photos.

Allowing your application to be extended by installing additional components to it is not an easy task. If your application consists of multiple smaller components that should work together, the easiest way to go on achieving this is by including the source code of those components into the application, build and deploy everything together. While you can allow the components to be built separately and then integrated at build time, this will not allow you to ship additional functionality in the future, unless you want to ship a new version of the software including that functionality.

This is where the Managed Extensibility Framework (MEF) comes into play. MEF allows your application to be extended using  components that are discovered and loaded at runtime without any kind of configuration.

 

How MEF Works

MEF is all about composition. It composes the application by combining what it calls parts. Parts are modules that are loading at runtime and made available for the application to use. A part exposes what functionality it can offer using exports, and defines its dependencies using imports.

MEF uses a “composition container” to match the imports to the exports.
Another component is the catalog, which MEF uses to discover any parts from a defined location and make it available to the application.

To demonstrate, we are going to build a very basic application. The application prints a message to a screen. The application will pass the message that needs printing to the modules that were discovered at runtime, and these modules will do the actual printing.

Our application will consist of 4 Visual Studio Projects as shown below

image

MEFSample: This project will be our main application, which will be responsible for loading all the parts (or modules)

Contract: This project will contain the interface that will define the contract between the main application and the parts

Part1 and Part2: These projects will implement the interface defined in the Contract project and will export their functionality to be consumed by the main application. These will be our modules.

The first thing we need to do is define the contract

public interface IPrint
{
    void PrintMessage(string message);
}

We then need to implement this interface in our parts. Below is an example

[Export(typeof(IPrint))]
public class Part1:IPrint
{
    public void PrintMessage(string message)
    {
        Console.WriteLine("Part 1: " + message);
    }
}

In the above code, you can see the attribute “Export”. This effectively means that this class exposes the functionality defined by the IPrint contract, and can be consumed by any application that requires this functionality.

At this point, our module is ready to be consumed by any application that requires it. Now we need to let our application look for and load the module. To do so we need to define a CompositionContainer and a catalog.

In our MEFSample Program class, we define the following

private CompositionContainer container;
public Program()
{
    AggregateCatalog catalog = new AggregateCatalog();
    string appPath= System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
    catalog.Catalogs.Add(new DirectoryCatalog("Modules"));
    container = new CompositionContainer(catalog);
    container.ComposeParts(this);
}

The above code defines a new CompositionContainer. It then defines a new AggregateCatalog and adds a new DirectoryCatalog to it that points to the Modules folder. This tells the application to look for parts in that folder.

We now define what modules the application is looking for

[ImportMany]
IEnumerable<IPrint> printers;

Here we are saying that our program will require all modules that implement the IPrint contract. At runtime, MEF will match imports and exports that have the same contract.

At this point our program is read to use the collection of printers.

static void Main(string[] args)
{
    Program prog = new Program();
    foreach (var item in prog.printers)
    {
        item.PrintMessage("Hello MEF");
    }
    Console.ReadKey();
}

With the above code, our application is ready to be built and run. If you run the application now as is, you will see an empty screen. This is because our modules folder is still empty. Go ahead and copy the dlls of both Par1 and Par2 projects into the modules folder. You have to create this folder inside the Debug folder of the MEFSample application. Once you do that and run the application again, you will see the output of both modules appear on the screen as follows

image

As you can see, using MEF it is incredibly easy to create applications that are extensible using modules and extensions.

The sample solution can be downloaded from here.

Comments
Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment