Metadata in MEF

Comments [0]

In previous articles, I showed how to create a simple MEF contract based on a string and a contract based on an Interface.

Recall that MEF uses a contract that matches Import and Export components at runtime.  Contracts are defined by Import and Export attributes applied to declarations and definitions, respectively.

In this article, I'll show how to add metadata to your export data and to read that metadata at runtime.

We'll start with the sample created in my article about Interfaces.  In this sample, we created three projects:

  • MEFInterface contains the IToDo interface.
  • MEFConsoleApp1 is our console application.  It contains the Import property based on the IToDo interface.
  • MEFComponent1 is a class library containing an exported property implementing the IToDo interface.

We can add metadata to an Export with the ExportMetaData attribute.  The ExportMetaData attribute accepts two parameters: the name and the value of metadata applied to that export.  When MEF imports this export, the metadata is imported as well and is accessible from code.  Below is an Export from our sample with the ExportMetaData attribute applied.

    [Export(typeof(IToDo))]
    [ExportMetadata("Priority", 2)]
    public class FirstTask : IToDo
    {
        ...
    }

We apply a similar attribute to the other Export in MEFComponent1

    [Export(typeof(IToDo))]
    [ExportMetadata("Priority", 1)]
    public class ImportantTask : IToDo
    {
        ...
    }

MEFConsoleApp1 contained an Import that declared a collection of IToDo objects. To access the metadata of this collection, we should change the declaration to an ExportCollection. An ExportCollection implements the IEnumerable interface, but also exposes MEF metadata.

        [Import(typeof(IToDo))]
        public ExportCollection ToDoList { get; set; }

The code telling MEF to match up contracts remains the same; but the code to access the data and metadata changes to loop through the ExportCollection, as shown below.

            foreach (Export exTd in ToDoList)
            {
                IToDo td = exTd.GetExportedObject();
                Console.WriteLine(td.TaskName);
                int priority = Convert.ToInt32(exTd.Metadata["Priority"]);
                Console.WriteLine("Priority=" + priority.ToString());
            }

In the above code, exTd is an Export object.  The Export object contains not only the IToDo object we imported (via the GetExportedObject method); it also allows us to retrieve metadata.  Since metadata is a set of name-value pairs, we can retrieve a value by passing the name to the Metadata collection.  In this case, we pass get the value of Metadata["Priority"].

In this article, we showed how to apply metadata to an MEF Export and how to retrieve that metadata at runtime.

Code: MEFDemo3.zip (574.93 KB)

Note: The code in this article uses MEF CTP 5.