2016-10-04 63 views
1

我试图将.NET框架应用程序的集合移植到.NET Core,并且作为此过程的一部分,我需要从使用MEF1切换到MEF2。我在解决与MEF2有关的问题时遇到了很多困难(虽然我发现this post真的很有帮助),但是最近我偶然发现了其中一个人的背后原因。为什么MEF2不会将元数据属性应用于所有零件导出?

特别是,我有许多类使用自定义ExportAttribute导出元数据,我想将它们全部导入到另一个类中,并根据此元数据对它们进行过滤。在MEF1中这一切都正常,但在MEF2中,我遇到了诸如“导出元数据为x”缺失并且没有提供默认值的问题。“

更具体地说,我批注我出口类象下面这样:

[Export(typeof(IClientRequestProcessor<RelaySystemModel>))] 
[TargetDevice("<<Foo>>")] 
internal class RelaySystemClientRequestProcessor : IClientRequestProcessor<RelaySystemModel> 
{ 
} 

然后在其他地方,我会尝试导入他们是这样的:

[ImportMany] 
public IEnumerable<ExportFactory<IClientRequestProcessor<RelaySystemModel>, DeviceSpecific>> RelayRequestProcessors { private get; set; } 

然后,对进口的满意度,尝试通过元数据过滤它们:

private static IEnumerable<ExportFactory<T, DeviceSpecific>> FilterForFoo<T>(IEnumerable<ExportFactory<T, DeviceSpecific>> items) 
{ 
    return from it in items where it.Metadata.DeviceId == "<<Foo>>" select it; 
} 

其中TargetDeviceAttribute是d efined如下:

[MetadataAttribute, AttributeUsage(AttributeTargets.Class)] 
public class TargetDeviceAttribute : ExportAttribute, IDeviceSpecific 
{ 
    public TargetDeviceAttribute(string deviceId) 
    { 
     this.DeviceId = deviceId; 
    } 

    public string DeviceId { get; private set; } 
} 

我发现发生的事情是,部分RelaySystemClientRequestProcessor有两个出口对应:IClientRequestProcessor<RelaySystemModel>,这是我很感兴趣的出口和接口我尝试导入带有的部分和RelaySystemClientRequestProcessor。但是,“DeviceId”元数据仅与相关联,而不是前者,这没有帮助。

MEF2-exports

有几种方法,我认为这是可以解决的,虽然我还没有完全测试:

  1. 应用属性ExportMetadata("DeviceId", "<<foo>>")我所有的出口部分。

  2. 更改TargetDeviceAttribute以使用构造函数public TargetDeviceAttribute(string deviceId, Type exportType) : base(exportType)

我不赞成这些解决方案;如果我想更改元数据密钥,前者会有问题,并且两者都会涉及更改我导出所有零件的方式。

我想知道的是,如果MEF2提供了一种导出MEF1中的元数据的方法:创建自定义元数据属性并使其适用于全部与零件关联的导出。这可能吗?

回答

0

原来我只是需要删除6个字符。相反,从ExportAttribute使TargetDeviceAttribute继承的,它应该只是从Attribute而不是继承:

[MetadataAttribute, AttributeUsage(AttributeTargets.Class)] 
public class TargetDeviceAttribute : Attribute, IDeviceSpecific 
{ 
    public TargetDeviceAttribute(string deviceId) 
    { 
     this.DeviceId = deviceId; 
    } 

    public string DeviceId { get; private set; } 
} 

在更一般的情况下,这意味着可以与多种可能的类型相关联,但任何元数据应当确保更好的静态类型安全/我应该像下面这样做ExportAttribute("foo", "bar")可维护性:

public interface IMetadataExtension 
{ 
    string Foo { get; } 
} 

public class MetadataExtension : IMetadataExtension 
{ 
    public string Foo { get; set; } 
} 

[MetadataAttribute] 
public class MetadataExtensionAttribute : Attribute, IMetadataExtension 
{ 
    public MetadataExtensionAttribute(string foo) 
    { 
     Foo = foo; 
    } 

    public string Foo { get; } 
} 

[Export] 
[MetadataExtension("bar")] 
public class SomeExport 
{ 

} 
相关问题