2

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

这样做的原因如下:我在 ListBox 中显示导入部件的名称和 typeof(int) 属性,并且在选择相应的 ListBoxItem 之前它们不会加载(非常标准)。现在我想在某个事件引发时更新一个部分的元数据信息,因此 ListBox 中显示的信息类似于“[Part name] ([new number])”。

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

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

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

我知道这个问题看起来很奇怪,但这并没有让它变得不那么困难,因此也很有趣;-)


编辑(基于李的回答,为了让人们了解问题的核心)

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

我在导出接口中添加了一个属性,该属性仅用于在 UI 中表示并进行更新,该属性没有其他功能,并且部分不被它过滤。

谢谢

4

1 回答 1

3

元数据过滤和 DefaultValueAttribute

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

引文

短版(在问题编辑后编辑)。

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

以前的帖子。

更改视图上的值将通过对加载的组件撒谎。当然,元数据只是返回初始化值的对象的接口;确保您可以在技术上更新这些值,但这不是元数据的目的。

您不会Name更改Type. 为什么不?因为它是元数据。在运行时更新元数据意味着真实数据实例的性质以某种方式被修改。

如果可能,这行代码不会引入 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 来处理。这是海事组织的大量工作。

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

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

然后,您有一个数据库/清单/xml,将贵公司设计的唯一永久静态零件编号映射到当前零件编号。控制 UI 中的修改会更新数据库/清单/xml。

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

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

于 2013-07-31T18:26:03.453 回答