Professional Documents
Culture Documents
Can we connect import and export via some defined contract rather than .NET data
types?
This looks very much similar to DI and IOC, why the re-invention?
Source Code
Reference
This FAQ deep dives into .NET 4.0 MEF fundamentals (Import and Export) and also explains
when to use MEF over DI / IOC. This article also explains step by step on how to use MEF in
various technologies like Silverlight, WPF and ASP.NET.
Please feel free to download my free .NET Ebook which has 400 questions and answers in
WCF, WPF, WWF, Silverlight and lot more from here.
MEF is a framework by which you can make your application extensible. For example, you
have an accounting application and you would like to provide a hook (socket) where
external vendors can connect (plug) and add invoicing capabilities to the accounting
application.
For instance, you have application which you would want different vendors to connect with
their features and extend your application.
So the vendors just put the components in the application, the application discovers them
and does the connection and extension.
Import (Create the socket): Use the Import attribute to define a hook or socket in your
application.
Export (Attach the Plug): Use the Export attribute to create the plug which can attach
to the plug or hook.
Compose (Extend it): Use the composition container and compose it.
Can We See A Simple Example of MEF with the Above 3 Steps?
We will create a simple class which will have a hook to import string message. In other
words, any class which has functionality of string message implementation can attach
themselves to the hook and extend that class.
The first step is to create a place holder / hook / socket where other components can plug
in.
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
The above import attribute says that anyone who has string functionality
implementation type can connect to me and attach the functionality.
In order to create the plug or extension, we need to use the Export attribute as shown
below. This attribute in the current scenario does nothing but displays a simple string.
class clsMySimpleMessage
{
[Export()]
string ExportMessage
{
set
{
}
get
{
return "Message inserted via MEF";
}
}
}
Ok, so we have created the socket, the plug and its time to connect both. Below goes the
code for the same:
// Once you have got the reference of catalog add it to the composition container.
CompositionContainer compositionContainer = new CompositionContainer(catalog);
In other words export, import and compose. The below figure summarizes the same:
Export is like things you give off and import is like things which you take in.
The types of import and export should match or else while composing you will get an error
as shown below. Can incompatible socket and plug connect?
Can We Connect Import and Export via Some Defined Contract
Rather than .NET Data Types?
In the real world, your hooks would be some real world contract types like customer,
supplier, etc. rather than simple .NET data types like string, int, Boolean, etc. In order
to create a real word kind of hook in MEF, we need to first create a contract using interfaces
as shown below:
interface ImyInterface
{
string getString();
}
We need to ensure that the hooks defined in both import and export attribute are of the
same interface type as shown below. The binding logic using composition container does not
change; its the same as described in the previous section.
class Program
{
[Import()]
public ImyInterface myInterface
{
set;
get;
}
}
This Looks Very Much Similar to DI and IOC, Why the Re-
invention?
Both of them overlap each other to a very great extent, but the GOALS are different. DI and
IOC is meant for decoupling, while MEF is for extensibility. The below requirement will throw
more light on how to decide which solution to go for:
Requirement Solution
The application should be a tiered application with each tier decoupled from each
DI IOC
other for better reusability and maintainability.
The application should provide a facility of exporting data into different formats.
External vendors should be able to plug in their own export mechanism into the MEF
application.
DI / IOC MEF
Decoupling Yes
Extensibility Yes
Registration Yes
DI / IOC MEF
Discovery Yes
Requirement Solution
The application should be 3 tier architecture with UI, BO and DAL layer
DI IOC
decoupled from each other.
The data access layer needs to be open and extensible. The application will
provide the ability to vendors to plug their own data connection mechanism so MEF
that application can connect to their proprietary databases.
The way to approach the first requirement is by using your favorite IOC container and the
second requirement is where MEF fits. The below diagram shows how they fit into the whole
game.
The end GOAL is more important when making a choice between them.
Here is a nice article by Mr. Nicholas Blumhardt which shows how MEF and IOC fit in.
Define the Silverlight items you want to import. In the below code snippet, we have defined
a collection of user control type.
Use Export to define the plug. For the current scenario, we have defined two Silverlight
user controls with export attribute exposing UserControl as the type.
[Export(typeof(UserControl))]
public partial class SilverlightControl1 : UserControl
{
public SilverlightControl1()
{
InitializeComponent();
}
}
[Export(typeof(UserControl))]
public partial class SilverlightControl2 : UserControl
{
public SilverlightControl2()
{
InitializeComponent();
}
}
CompositionInitializer.SatisfyImports(this);
If you run the same, you should see the composed user controls in the main Silverlight UI
container as shown below: