MEF allows composable parts to provide their metadata. Metadata here is a set of statically-known properties, which is typical for part type, not for the type instance.
Suppose you're building a GUI for calculator in the given example.
Each operation is a plugin here, which being loaded via MEF container. You don't want to instantiate every plugin until user selection, but you want to build the panel with buttons, where each button holds an operation symbol.
That's why you need to use metadata instead of adding char Symbol {get;}
to IOperation
:
- you can access metadata without instantiation of part (this could be expensive);
- the metadata belongs to the composable part, and every instance of that part should have the same metadata (although calculator example isn't a good choice for understanding that fact).
You're describing metadata interface IOperationData
and applying ExportMetadata
attribute to the composable part definition. Then, at run-time, MEF looks at Add
class, and dynamically builds IOperationData
implementation. The instance of that implementation being initialized with values, provided in ExportMetadata
. And, finally, you can access the values of IOperationData
implementation with Add.Metadata.Smybol
later in host application.
UPDATE.
ExportMetadata
allows you to add multiple metadata values, but it is often more convenient to add metadata, using custom attribute, which is inherited from ExportAttribute
:
public interface IMyPlugin {}
public interface IMyMetadata
{
int Value1 { get; }
string Value2 { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class MyExportAttribute : ExportAttribute, IMyMetadata
{
public MyExportAttribute(int value1, string value2)
: base(typeof(IMyPlugin))
{
Value1 = value1;
Value2 = value2;
}
public int Value1 { get; private set; }
public string Value2 { get; private set; }
}
Usage:
[MyExport(1, "Orange")]
public class MyPlugin : IMyPlugin {}