ASP.NET MVC + MEF + MefContrib: Can't seem to get metadata from Exports
I'm using asp.net mvc3 with MEF + MEFContrib to load some services on my controllers. What's happening is that I can load the services - IEnumerable<IPublishService> publishers
- with the [ImportingConstructor]
but when I try to load the services with metadata - Lazy<IPublishService, IPluginMetaData>[] publishers
- I get an empty array.
Any thoughts on why? Thanks.
My code:
public interface IPluginMetaData
{
string Name { get; }
string Version { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginMetadataAttribute : ExportAttribute
{
public PluginMetadataAttribute(string name, string version)
: base(typeof(IPluginMetaData))
{
Name = name;
Version = version;
}
public string Name { get; set; }
public string Version { get; set; }
}
[Export(typeof(IPublishService))]
[PluginMetadata("Default", "1.0.0.0")]
public class SamplePublishService : IPublishService
{
}
[ImportingConstructor]
public HomeController(Lazy<IPublishService, IPluginMetaData>[] publisher /* Empty Array */ , IEnumerable<IPublishService> publishers /* Array with 1 service */)
{
}
UPDATE (based on Daniel answer but still nothing)
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class PluginMetadataAttribute : ExportAttribute
{
public PluginMetadataAttribute(string name, string version)
: base(typeof(IPublishService))
{
Name = name;
Version = version;
}
public string Name { get; set; }
public string Version { get; set; }
}
[PluginMetadata("Default", "1.0.0开发者_如何学运维.0")]
public class GoogleSampleGroupPublishService : IPublishService
{
}
[ImportingConstructor]
public HomeController([ImportManyAttribute]Lazy<IPublishService, IPluginMetaData>[] publisher)
{
}
Normally, you would need to put an ImportManyAttribute
on the arguments to your constructor, since they are collection imports. Since one of them is working, I suspect that MEFContrib is doing something so that you don't need to do this, but it only works for IEnumerable<T>
and not an array of T. So try changing the first argument to IEnumerable<Lazy<IPublishService, IPluginMetadata>>
, or adding an ImportManyAttribute
in front of it.
Some other issues I noticed: Your PluginMetadataAttribute
is derived from ExportAttribute
. The reason you would do that is so that you don't have to put both an export and a metadata attribute on your services. However, the type that you pass to the base class constructor is the exported contract. So this should be IPublishService
instead of IPluginMetadata
. Make that change and remove the Export attribute from SamplePublishService.
精彩评论