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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With