I want to export type Foo
with multiple metadata options:
public interface IFoo
{
void Do ();
}
[ExportFoo ("Bar", "1.0")]
[ExportFoo ("Baz", "1.0")]
[ExportFoo ("Baz", "2.0")]
public class Foo : IFoo
{
public void Do () {}
}
I have declared ExportFooAttribute
this way:
public interface IFooMeta
{
string Name { get; }
string Version { get; }
}
[MetadataAttribute, AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
public class ExportFooAttribute : ExportAttribute, IFooMeta
{
public string Name { get; private set; }
public string Version { get; private set; }
public ExportFooAttribute (string name, string version) : base(typeof(IFoo))
{
Name = name;
Version = version;
}
}
According to documentation, when AllowMultiple
is set to true
, metadata actually contains arrays of properties of the original metadata, so I import types this way:
public interface IFooMultiMeta
{
string[] Name { get; }
string[] Version { get; }
}
public class Program
{
[ImportMany]
public List<Lazy<IFoo, IFooMultiMeta>> Foos { get; set; }
private static void Main ()
{
new Program().MainInternal();
}
private void MainInternal ()
{
new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly())).ComposeParts(this);
foreach (Lazy<IFoo, IFooMultiMeta> lazyFoo in Foos)
for (int i = 0; i < lazyFoo.Metadata.Name.Length; i++)
Console.WriteLine("* {0} {1}", lazyFoo.Metadata.Name[i], lazyFoo.Metadata.Version[i]);
Console.WriteLine(Equals(Foos[0].Metadata, Foos[1].Metadata));
Console.ReadKey();
}
}
I expected to get one instance of Foo
with metadata which contains arrays of 3 values. However, I got this:
* Baz 2.0
* Baz 1.0
* Bar 1.0
* Baz 2.0
* Baz 1.0
* Bar 1.0
* Baz 2.0
* Baz 1.0
* Bar 1.0
False
What's worse, metadata instances are different, so I can't even properly filter out duplicates.
Question: How to properly export one class as satisfying multiple combinations of metadata properties?
Complete sample: http://pastebin.com/WyjN95gr
The reason for the three exports is the fact that you derive your custom export metadata from the ExportAttribute
. This means that for each decoration a different export is taking place. Three decorations lead to three exports.
I'm not sure why you get all {Name,Version} pairs for each export.
To overcome the three exports you can update your custom attribute to derive from Attribute instead:
[MetadataAttribute, AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
public class ExportMetaFooAttribute : Attribute, IFooMeta
{
public string Name { get; private set; }
public string Version { get; private set; }
public ExportFooAttribute (string name, string version)
{
Name = name;
Version = version;
}
}
I have renamed it to ExportMetaFooAttribute
since it is not an export attribute but an export metadata attribute.
Then you change your Foo
class to:
[Export(typeof(IFoo))]
[ExportMetaFoo("Bar", "1.0")]
[ExportMetaFoo("Baz", "1.0")]
[ExportMetaFoo("Baz", "2.0")]
public class Foo : IFoo
{
public void Do ()
{}
}
As you can see now we need the extra ExportAttribute
to specify that this class needs to be exported.