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.
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:
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.
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.
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.
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:
So, what’s going on internally? If you debug your code, you will notice that the catalog has two Parts “Customer
” and “Employee
”.
Also, it populated the collection property. Here it is:
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