Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

First Guide to MEF and Silverlight (Part–I)

0.00/5 (No votes)
15 Aug 2010 1  
In this article, I described little about MEF and then described it in depth using a Console Application. Read it and don't forget to vote and share your feedback.

Introduction

MEF is a framework to extend your application and was introduced in .NET Framework 4.0 and Silverlight 4.0. Recently I got a chance to look around the MEF with Silverlight. I found it useful in various scenarios and thus thought of doing something with MEF in Silverlight.

In this article, I will first discuss little about the MEF framework to give you some basic knowledge about it and then will show you how to create a small HelloMEFWorld console application step-by-step. In the next article, I will use it in a Silverlight application & showcase you the feature and functionality. Read through the whole article and use this extender in your application if you need. Don’t forget to share your feedback and suggestions as this helps me improve my articles in greater details and present more to you.

Table of Contents

  • Introduction to MEF
  • How MEF Works?
  • Why to use MEF in our Application?
  • Exporting a Class
  • Importing via Property
  • Doing Composition using the CompositionContainer
  • Building our First HelloMEFWorld application
    • Setting up the Project
    • Exporting Contract
    • Importing Contract
    • Setting up the CompositionContainer
  • Application Demo
  • End Note

Introduction to MEF

MEF, i.e., Managed Extensibility Framework is a component of .NET Framework 4.0 and also added support for Silverlight 4.0. It actually simplifies the creation of extensible applications using extensions to develop encapsulated code without any hard dependencies. Its uses are like Prism and/or Dependency Injection (I will prefer to say) as it gives us the opportunity to develop an independent module. More precisely, it is an independent module with compositions to create a full pledged application.

image

If you are using .NET 4.0, there is no need to search a separate download for it. You need to add the reference of some DLLs which come with your .NET Runtime. If you are using earlier releases of .NET 4, you can find it hosted with full source code at CodePlex MEF Site.

If you want to know about the Architecture, visit CodePlex MEF Site for the Architecture Overview.

How MEF Works?

MEF’s core is contained with Catalog and Composition Container. Catalog is responsible for discovering extensions in your application and the Composition Container is responsible for Coordinates creation and dependency satisfaction. Catalog allows application to consume Exports which are registered via the Export Attributes whereas the CompositionContainer exposes methods to get those Exports to use in your application.

Here is the diagram of a simple MEF structure:

image

The first thing in MEF is the Composable Parts which offers one or more Exports and depends on external services like Imports. A Composable Part is a composable unit which actually exports services & imports by other Composable Part. They are dependable with one another via Contracts and those contracts are marked as either Imports or Exports using the Attributes “System.ComponentModel.Composition.Import” and “System.ComponentModel.Composition.Export”. Every export has the contract & every import declares the contract that it needs. These contacts are the bridge between imports & exports.

The Composition Container interacts with the Catalog to have access to the composable parts and the part returned by the catalog is the extension that your application needs. Based on the imports & exports, the composition container loads it in the application unit.

Why to use MEF in our Application?

MEF solves the dependency between two modules in an application and also solves the runtime extensibility problem. The extensions by their implementation & working nature can be reused by various applications or a single application. They may be dependent to each other but the MEF will take care of the order it is supposed to load. So, if you are in a need to provide runtime extensibility support for your application, you can use this framework very easily and provide your application to your clients with plug-in supports.

This is sometimes helpful when you want to load an assembly on demand from a specific location. I will show you later how to do this.

Visual Studio 2010 supports MEF and you can extend the application with the MEF extensibility. More content can be found in CodePlex MEF Site. Read about it more and implement the same in your next applications.

Now, let us discuss more about each topic to implement a MEF application. We'll start with the concept and then we will create one small application.

Exporting a Class

Exporting a class is very easy. You just have to mark your contract with the attribute named “System.ComponentModel.Composition.Export”. Once done, your contract class will export automatically by the MEF for importing. Let's see how to do that:

[Export(typeof(IPerson))]
public class Employee : IPerson
{

}

Importing via Property

This is like Dependency Injection. You have to mark your property of the same type with the "System.ComponentModel.Composition.Import" attribute. This will import a single instance of the type to the property in your Composition Container. Let's see the code for that:

public class Program
{
    [Import]
    public IPerson Persons { get; set; }
}

If you want to import a collection of the exported type, you need to set the "System.ComponentModel.Composition.ImportMany" attribute to the property and the property should be declared as Collection. Let's see in code:

public class Program
{
    [ImportMany]
    public IPerson[] Persons { get; set; }
}

Doing Composition using the CompositionContainer

CompositionContaner constructs all the parts and initializes them for the use. First, you need to create the catalog and then you have to compose the parts from the composition container. There are four types of Catalog available: "AggregateCatalog", "AssemblyCatalog", "DirectoryCatalog" and "TypeCatalog". AggregateCatalog contains mutable collection of ComposablePartCatalog objects. AssemblyCatalog contains immutable ComposablePartCatalog objects created from managed code assembly. DirectoryCatalog represents ComposablePartCatalog objects from a contents of Directory path. TypeCatalog is an immutable object of ComposablePartCatalog that is created from a Type array or a list of managed types.

Let's see some sample code for that. First, we will create the catalog from executing assembly and in the next step we will create it from a directory location.

private void CreateCompositionContainerFromAssembly()
{
    AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
    CompositionContainer compositionContainer = new CompositionContainer(catalog);
    compositionContainer.ComposeParts(this);
}

private void CreateCompositionContainerFromDirectory()
{
    DirectoryCatalog catalog = new DirectoryCatalog(@".\");
    CompositionContainer compositionContainer = new CompositionContainer(catalog);
    compositionContainer.ComposeParts(this);
}

Building our First HelloMEFWorld Application

Now we got some basic idea on the MEF. Let us try implementing a small application. It will give us more knowledge on it. We will break it in some small pieces and will do it step-by-step.

To develop our first MEF application, we need our development environment with the following things setup before we start:

  • Visual Studio 2010 IDE (includes .NET 4.0)

Once our development environment is ready, we can jump to the next step to create the project.

Setting up the Project

In this article, I will make a Console application. In the next article, I will describe it for Silverlight. Hence, open your Visual Studio 2010 and create a Console Application. Be sure that you selected the .NET 4.0 Framework while creating the project.

image

Once the project has been created by the IDE, you need to add a reference of the Assembly named “System.ComponentModel.Composition” to your project. To do this, right click on your Console Application project and click “Add Reference”.

From the “Add Reference” dialog, find the assembly named" “System.ComponentModel.Composition” and add it to your project.

image

Now your project is ready for the MEF development. Let’s create the basic project structure with the necessary interfaces and classes. This will helpful for us later while doing the MEF integration.

First, we will start designing our interface named “IPerson” with a method call WriteMessage(). Here is the code for that:

namespace HelloMEFWorld
{
    public interface IPerson
    {
        void WriteMessage();
    }
}

Now it's time to implement the interface. We will create two classes named "Customer" and "Employee" inherited from the interface IPerson. We must have to implement the interface method. Let's do it with some proper message writing to the Console:

namespace HelloMEFWorld
{
    public class Customer : IPerson
    {
        public void WriteMessage()
        {
            Console.WriteLine("I am your Customer");
            Console.ReadLine();
        }
    }
}

namespace HelloMEFWorld
{
    public class Employee : IPerson
    {
        public void WriteMessage()
        {
            Console.WriteLine("I am your Employee");
            Console.ReadLine();
        }
    }
}

Exporting Contract

It’s time for exporting the contract so that we can use it in our application. To do this, what do we have to do? Exactly, you are right. We have to mark the contact class as Exportable using the Export attribute. Now, we will do it for only the Customer class. Hence, open your Customer class and set its attribute to Export of type IPerson. Here's the code:

using System;
using System.ComponentModel.Composition;

namespace HelloMEFWorld
{
    [Export(typeof(IPerson))]
    public class Customer : IPerson
    {
        public void WriteMessage()
        {
            Console.WriteLine("I am your Customer");
            Console.ReadLine();
        }
    }
}

Your “Customer” class is ready for Export. Now we need to import it in the “Program” class.

Importing Contract

To import a contract, we need to create a property. I already mentioned it while describing at the top. Let us create the property of type IPerson. We will use this type so that we can import both the Customer and Employee. So, open the Program.cs file and create a property named "Persons" of an array type of IPerson. Set the attribute of the property to ImportMany. If you want to do it for a single instance of IPerson, use a IPerson type of property and mark as "Import". In our example, we are using IPerson[] and hence marked as ImportMany.

using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;

namespace HelloMEFWorld
{
    public class Program
    {
        [ImportMany]
        public IPerson[] Persons { get; set; }

        static void Main(string[] args)
        {

        }
    }
}

Now we will create one method which will iterate through the collection and call the WriteMessage() method of IPerson. Then we will call it from the Main method of the Person class. The full code, which will look like below:

using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;

namespace HelloMEFWorld
{
    public class Program
    {
        [ImportMany]
        public IPerson[] Persons { get; set; }

        static void Main(string[] args)
        {
            Program p = new Program();
            p.ListAllPersons();
        }

        private void ListAllPersons()
        {
            foreach (var person in Persons)
            {
                person.WriteMessage();
            }
        }
    }
}

If you run your application, we will get NullReferenceException, because the Persons collection is null. So, let's populate the collection. How to do that? Read the next point for that.

Doing Composition using the CompositionContainer

Populating the collection is easy, right? You need to create an instance of Customer class and add it to the collection. Am I right? Wait, that's wrong in MEF. If you want to populate it like this, then what is the need of MEF? MEF gives you application development without direct dependency to a module. So, what to do? We have to create the catalog first and then compose the parts from the CompositionContainer as mentioned earlier. Let's create a different method to do the same.

private void CreateCompositionContainer()
{
    AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
    CompositionContainer compositionContainer = new CompositionContainer(catalog);
    compositionContainer.ComposeParts(this);
}

Now call the method CreateCompositionContainer() from the ListAllPersons() method. Do it at the first line before iterating through the collection. This will initialize the collection property with the exported contracts.

Application Demo

As our Composition Container is ready, run the application and now you will not encounter any Exception. You will see the WriteMessage() of Customer class has been called automatically and it wrote the message "I am your Customer" to the screen.

image

We didn't write any specific code to create the instance of the Customer class. It is done automatically by the MEF. It will load the instance in the property while composing the Container. Now we will add the Employee class to here. To do this, just add the Export attribute to the contract class. This is same as we did for the Customer class. But for your reference, here is the code:

using System;
using System.ComponentModel.Composition;

namespace HelloMEFWorld
{
    [Export(typeof(IPerson))]
    public class Employee : IPerson
    {
        public void WriteMessage()
        {
            Console.WriteLine("I am your Employee");
            Console.ReadLine();
        }
    }
}

Run your application once again. Waooo!!! It created the Employee class too! No need to write any extra code for integrating the Employee class. That's MEF. It gives you smooth extensibility for your application without modifying the original code. If you know about its type, that's it. It will do the things. Here is the snapshot of the output:

image

So, what’s going on internally? If you debug your code, you will notice that the catalog has two Parts “Customer” and “Employee”.

image

Also, it populated the collection property. Here it is:

image

End Note

So, what’s now? Hope you got the basic knowledge on the MEF framework and also got the idea on what we can do using the MEF. So, explore it and use in your project if require. In my next article, I will show you how to use it in a Silverlight application. Till then, enjoy using MEF reading my articles.

If you have any feedback or suggestions, please don’t hesitate to share them here. I always appreciate your time for reading my articles and also sharing your feedback.

Please vote for this article.

History

  • 15th August 2010: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here