I got a CompositionContractMistachException
when using a custom attribute class in MEF on .NET 4.0.
Unable to create an instance of the Metadata view '(snip).ModuleExportAttribute, (snip), Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because a constructor could not be selected. Ensure that the type implements a constructor which takes an argument of type IDictionary<string, object>.
Here is my ModuleExportAttribute
class, nothing special:
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class ModuleExportAttribute : ExportAttribute
{
public ModuleExportAttribute(string name) : base(typeof(IModule))
{
this.Name = name;
}
public string Name { get; private set; }
}
The usage is like this:
[ModuleExport("MyModule")]
public class MyModule : IModule
{
...
}
After adding the asked constructor, the exception goes away.
However, I couldn't find any reference that states this requirement. On the opposite, I saw many examples and blog posts using custom attribute class without such constructor. Am I missing something here?
How are you trying to import this? I suspect the error is caused by you importing something like Lazy<IModule, MetadataExportAttribute>
in which case yes in order to use a concrete type as the metadata type it must either be an interface, in which case we generate a proxy type or it must be a type that takes an IDictionary<string,object>
so that the metadata can be passed to it.
Try something like:
public interface IModuleMetadata
{
string Name { get; }
}
Then change your import to something like:
[Import]
Lazy<IModule, IModuleMetadata> Module;
I also like to have my ExportAttribute implement the IModuleMetadata interface to make sure they stay consistent but that isn't absolutely necessary.