gpt4 book ai didi

c# - 为什么 MEF2 不将元数据属性应用于所有零件导出?

转载 作者:行者123 更新时间:2023-11-30 17:36:18 26 4
gpt4 key购买 nike

我正在尝试将一组基于 .NET Framework 的应用程序移植到 .NET Core,作为此过程的一部分,我需要从使用 MEF1 切换到 MEF2。我一直难以理解与 MEF2 相关的问题(尽管我发现 this post 真的很有帮助),但我最近偶然发现了其中一个问题背后的原因。

特别是,我有许多使用自定义 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定义如下:

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

public string DeviceId { get; private set; }
}

我发现发生的事情是部分 RelaySystemClientRequestProcessor对应于两个exports:IClientRequestProcessor<RelaySystemModel> ,这是我感兴趣的导出和我尝试导入零件的界面,以及 RelaySystemClientRequestProcessor .但是,“DeviceId”元数据与后者而不是前者相关联,这没有帮助。

MEF2-exports

虽然我还没有完全测试,但我相信有几种方法可以解决这个问题:

  1. 应用属性 ExportMetadata("DeviceId", "<<foo>>")到我所有的导出零件。

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

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

我想知道 MEF2 是否提供了一种导出元数据的方法,就像在 MEF1 中一样:通过创建自定义元数据属性并将该元数据应用到与部件关联的所有 导出。这可能吗?

最佳答案

原来我只需要删除 6 个字符。与其让 TargetDeviceAttribute 继承自 ExportAttribute,不如继承 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
{

}

关于c# - 为什么 MEF2 不将元数据属性应用于所有零件导出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39847880/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com