MEF更新导出的零件元数据(元数据视图无效,因为属性具有属性集方法)

本文关键字:元数据 属性 方法 因为 无效 零件 更新 MEF 视图 | 更新日期: 2023-09-27 18:25:38

我有一个应用程序,我正在使用MEF来编写它。我想知道是否可以在导入零件后更新零件的元数据信息。

这样做的原因如下:我在ListBox中显示导入部件的名称和typeof(int)属性,直到选择了相应的ListBoxItem(相当标准),才会加载它们。现在我想在某个事件发生时更新一个部件的元数据信息,所以ListBox中显示的信息类似于"[部件名称]([新编号])"。

我将元数据导入为一个定义其信息的接口,但当我将int属性设置为可编辑(使用设置的accesor)时,我在合成时收到以下执行:

"The  MetadataView 'myMetadataInterface' is invalid 
 because property 'myInt' has a property set method."

有什么办法可以做到这一点吗?还是元数据总是在创建零件后才读取?

我知道这个问题看起来很奇怪,但它并没有减少它的难度,因此也很有趣;-)


EDIT(根据李的回答,为了让人们了解问题的核心)

我只是想知道是否可以在组成零件之后,但在实际加载之前更新元数据属性(HasValue==false)。不要担心过滤或查找零件。

我在导出接口中添加了一个属性,它只在UI中表示并更新,这个属性没有其他功能,部件也没有被它过滤。

感谢

MEF更新导出的零件元数据(元数据视图无效,因为属性具有属性集方法)

元数据过滤和DefaultValueAttribute

指定元数据视图时,将对仅匹配那些包含定义的元数据属性的导出在视图中。您可以在元数据视图上指定属性不需要,通过使用System.ComponentModel.DefaultValueAttribute。下面可以看到我们在IsSecure上指定了一个默认值false。这意味着如果部分导出IMessageSender,但不提供IsSecure元数据,那么它仍然将被匹配。

引文

简短版本(在问题编辑后的中编辑)。

您不应该在运行时更新元数据。如果您有一些数据应该更新并且属于mef部分,则需要选择通过重新编译进行更新,或者将该数据存储在dll之外的灵活存储中。如果不重新编译,就无法将您所做的更改存储在dll中,因此这是一个有缺陷的设计。

上一篇文章

更改视图上的值会导致对加载的组件撒谎。当然,元数据只是返回初始化值的对象的接口;当然,从技术上讲,您可以更新这些值,但这不是元数据的目的。

您不会更改Type实例的Name字段。为什么不呢?因为它是元数据。在运行时更新元数据意味着实际数据实例的性质在某种程度上被修改了。

如果可能的话,这行代码不会引入Triple类型。

typeof(Double).Name = "Triple";
var IGotATriple = new Triple();

如果您想更改值,只需要使用该信息创建另一个对象并绑定到该对象。元数据是在中编译的。如果你在加载零件后更改它,它不会更改零件源中的任何内容,所以你在撒谎。(除非您有权访问源代码,并在那里对其进行更改和重新编译)。

让我们看一个例子:

[Export(typeof(IPart))]
[ExportMetadata("Part Name","Gearbox")]
[ExportMetadata("Part Number","123")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class GearBoxPart : Part { public double GearRatio ... }

现在,让我们假设您有一个显示可用零件及其编号的UI。现在,无论出于何种原因,制造商都会更改零件号,而您想要更新它。如果可能,您可能需要考虑将零件号存储在清单或数据库中。或者,每次零件号更改时都必须重新编译。

重新编译是可能的。您有一个执行上述操作的控制器UI,但您没有更新元数据,而是提交了一个重建零件代码文件的请求。该请求将通过解析代码文件、替换零件号来处理,然后发送进行批量重新编译并重新分发新的dll。这是一个很大的工作,没有任何IMO.

所以,你设置了一个数据库。然后将对象元数据更改为此。

[ExportMetadata("OurCompanyNamePartNumber","123")]

然后,您就有了一个数据库/manifest/xml,它将您公司设计的唯一永久静态零件号映射到当前零件号。控件UI中的修改将更新数据库/manifest/xml。

<PartMap>
    <PartMapEntry OurCompanyNamePartNumber="123" ManufacturerPartNumber="456"/>
    ...
</PartMap>

然后,最终用户UI按制造商零件号查找零件,mef代码在PartMap中查找以获得mef零件号。