开发者

ASP.NET MVC + MEF + MefContrib: Can't seem to get metadata from Exports

开发者 https://www.devze.com 2023-02-13 06:49 出处:网络
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 [Imp

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消