元数据过滤和 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 零件号。