tofutim
tofutim

Reputation: 23374

A metadata view must be a concrete class with a parameterless or dictionary constructor

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

Answers (1)

David
David

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

Related Questions