Reputation: 23374
System.Composition.Hosting.CompositionFailedException: The type 'ITranslatorMetaData' cannot be used as a metadata view. A metadata view must be a concrete class with a parameterless or dictionary constructor.
I'm just getting started with MEF in PCL (using the nuget Microsoft.Composition). I believe this is the "lightweight" MEF. In my implemented class I have
[Export(typeof(ITranslator))]
[ExportMetadata("Source", "Microsoft")]
[ExportMetadata("Order", "2")]
And I have an interface called ITranslatorMetaData
public interface ITranslatorMetaData
{
[DefaultValue("Unknown")]
string Source { get; }
[DefaultValue(Int32.MaxValue)]
int Order { get; }
}
Finally, I try to import them using
[ImportMany]
private Lazy<ITranslator, ITranslatorMetaData>[] _translators { get; set; }
What am I doing wrong? Seems like this should just work.
Update I tried this to no avail.
[Export(typeof(ITranslator)),
ExportMetadata("Source", "Microsoft"),
ExportMetadata("Order", "2")]
Update 2 I did find an error, the Order should be an int not a string. But I still get the same error after specifying
[Export(typeof(ITranslator)),
ExportMetadata("Source", "Microsoft"),
ExportMetadata("Order", 2)]
Update 3 One proposed solution suggests I should not use an interface for the metadata, though the MEF examples in http://mef.codeplex.com/wikipage?title=Exports%20and%20Metadata&referringTitle=Guide clearly show using an interface for the metadata, rather than a concrete class.
Upvotes: 3
Views: 759
Reputation: 10708
As the exepction says, you must use a concrete class for the Metadata.
what this means is that interface
and abstract class
(EDIT: also static class
) types are not allowed, since the MEF code would have no idea what to construct when pulling up the necessary Metadata.
Thus, if you change interface ITranslatorMetaData
to class TranslatorMetaData
like so
public class TranslatorMetaData
{
[DefaultValue("Unknown")]
string Source { get; set; }
[DefaultValue(Int32.MaxValue)]
int Order { get; set; }
}
The code is able to compile.
With regard to the constructor, a parameterless public constructor is assumed in the lack of other constructors, thus why the above code fits the necessary parameters. However, specifying a constructor with parameters will leave a class without a constructorless parameter, and result in the same error unless using the "dictionary" constructor mentioned in the error.
Upvotes: 5