How can I make the following code work? It throws an error saying that there are two meta data attributes of identical names, though I do not see why.
The error message is as follows:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.ComponentModel.Composition.dll
Additional information: Member or Type 'ConsoleApplication2.DoSomeMagic' contains multiple metadata entries with the name 'PluginName'. The metadata entries could be coming from the ExportMetadataAttribute or from a property of a custom metadata attribute. Either remove the duplicate entries or enable the metadata entry with name 'PluginName' to allow multiple entries via the IsMultiple property on ExportMetadataAttribute or AttributeUsage.AllowMultiple on custom metadata attributes.
class Program
{
static void Main(string[] args)
{
var program = new Program();
program.Test();
}
private void Test()
{
//Export
var catalog = new AssemblyCatalog(this.GetType().Assembly);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
//Import Meta Data
var import1 = container.GetExports<IMagic1, IPluginAttributeView>().Select(e => new PluginAttribute(e.Metadata));
}
}
public interface IPluginAttributeView
{
string PluginName { get; set; }
string PluginConfigurationName { get; set; }
string PluginCategory { get; set; }
Type PluginType { get; set; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginAttribute1 : ExportAttribute, IPluginAttributeView
{
public string PluginName { get; set; }
public string PluginConfigurationName { get; set; }
public string PluginCategory { get; set; }
public Type PluginType { get; set; }
public PluginAttribute1(string pluginName, string pluginConfigurationName, string pluginCategory, Type pluginType)
: base(pluginType)
{
PluginName = pluginName;
PluginConfigurationName = pluginConfigurationName;
PluginCategory = pluginCategory;
PluginType = pluginType;
}
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginAttribute2 : ExportAttribute, IPluginAttributeView
{
public string PluginName { get; set; }
public string PluginConfigurationName { get; set; }
public string PluginCategory { get; set; }
public Type PluginType { get; set; }
public PluginAttribute2(string pluginName, string pluginConfigurationName, string pluginCategory, Type pluginType) : base(pluginType)
{
PluginName = pluginName;
PluginConfigurationName = pluginConfigurationName;
PluginCategory = pluginCategory;
PluginType = pluginType;
}
}
public class PluginAttribute
{
public string PluginName { get; set; }
public string PluginConfigurationName { get; set; }
public string PluginCategory { get; set; }
public Type PluginType { get; set; }
public PluginAttribute(IPluginAttributeView view)
{
PluginName = view.PluginName;
PluginConfigurationName = view.PluginConfigurationName;
PluginCategory = view.PluginCategory;
PluginType = view.PluginType;
}
}
public interface IMagic1
{
void DoMagic1();
}
public interface IMagic2
{
void DoMagic2();
}
[PluginAttribute1("PluginName1", "PluginConfig1.json", "Magic1", typeof(IMagic1))]
[PluginAttribute2("PluginName2", "PluginConfig2.json", "Magic2", typeof(IMagic2))]
public class DoSomeMagic : IMagic1, IMagic2
{
public void DoMagic1()
{
}
public void DoMagic2()
{
}
}
I found the solution after digging through many MEF related blogs and articles. The problem seemed that the imported MetaData is of type
IDictionary<string, object
. I hope it helps some that may have struggled with similar issue: