# Saturday, August 29, 2009

In Preview 6 of Microsoft's Managed Extensibility Framework (MEF), the framework changed the rules on matching multiple exports to a single import.

In previous versions of MEF, the attribute syntax was identical whether we were matching a single item or multiple items to an Import. Both scenarios used the [Import] attribute to tell MEF to find exports with a matching contract.

For example, if your application is using MEF to match a string variable, based on a string contract, you would use code similar to the following

[Import("MyMEFString")]
string SomeString { get; set; }

This works if MEF finds exactly one matching export string, as in the following code.

[Export("MyMEFString")]
string ThatExportedMefString
{
    get
    {
        return "This string was provided by an MEF contract.  It is from  an external assembly.";
    }
}

If there is a chance MEF might find multiple Exports that satisfy the above contract, you would need (in previous versions) to modify the imported type, so that it implements IEnumerable, as in the following example

[Import("MyMEFString")]
IEnumerable<string> SomeStringList { get; set; }

Beginning with MEF Preview 6, the rule for the attribute becomes more strict. If you are matching a number of items into an IEnumerable set of items on your import, you must replace the Import attribute with the ImportMany attribute. In the above example, the Import declaration becomes

[ImportMany("MyMEFString")]
IEnumerable<string> SomeStringList { get; set; }

The main advantage of this change is that ImportMany will not blow up if MEF finds no matching export for the contract. Import throws an exception if it cannot find a matching export.

Of course, your code will need to handle cases in which there are 0 matches, 1 match, or many matches when MEF seeks exports to match this contract. In the above example, that code might look like

foreach (string s in SomeStringList)
{
    Console.WriteLine(s);
}

In my opinion, when you are writing an Import and you don't have control over the Export (for example, if you are allowing third-party vendors to supply the matching Exports), you should always use the ImportMany attribute. The only time you should use the Import attribute is if you are only looking for contract matches in assemblies that you have written and you can guarantee that there will always be exactly one match.

MEF