Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MEF更新导出的零件元数据(元数据视图无效,因为属性具有属性集方法)_C#_Wpf_Mef_Ioc Container - Fatal编程技术网

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

C# MEF更新导出的零件元数据(元数据视图无效,因为属性具有属性集方法),c#,wpf,mef,ioc-container,C#,Wpf,Mef,Ioc Container,我有一个应用程序,我正在使用MEF来编写它。我想知道导入零件后是否可以更新零件的元数据信息 这样做的原因如下:我在列表框中显示导入部件的名称和typeof(int)属性,并且在选择相应的ListBoxItem之前不会加载它们(相当标准)。现在,我想在引发某个事件时更新某个部件的元数据信息,因此列表框中显示的信息类似于“[part name]([new number])” 我将元数据作为定义其信息的接口导入,但当我将int属性设置为可编辑(使用set accesor)时,我在合成时收到以下执行选项

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

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

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

"The  MetadataView 'myMetadataInterface' is invalid 
 because property 'myInt' has a property set method."
有没有办法做到这一点?或者元数据总是在创建零件后才读取

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


编辑(基于Lee的回答,以使人们了解问题的核心)

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

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

谢谢

元数据筛选和DefaultValueAttribute

指定元数据视图时,将对其进行隐式筛选 仅匹配包含定义的元数据属性的导出 在视图中。您可以在元数据视图上指定属性为 不需要,通过使用 System.ComponentModel.DefaultValueAttribute。下面你可以看到哪里 我们在IsSecurity上指定了默认值false。这意味着如果 部件导出IMessageSender,但不提供IsSecure元数据, 然后它仍然会被匹配

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

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

以前的帖子。

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

您不会更改
类型
实例的
名称
字段。为什么不呢?因为它是元数据。在运行时更新元数据意味着实际数据实例的性质会以某种方式被修改

如果可能的话,这行代码不会引入三元组类型

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")]
然后,您有一个数据库/manifest/xml,它将您公司设计的唯一永久静态零件号映射到当前零件号。控件UI中的修改将更新数据库/manifest/xml

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

...

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

谢谢您的回答。我不明白你说的“这么说你在撒谎”是什么意思,能解释一下吗?您最后的评论是我想要实现的:根据需要更新与mef零件元数据关联的数据。。。你能举个简单的例子或指导方针吗?再次感谢。您的元数据视图描述了您将检索的类型的查询,在运行时更改它本质上是对您检索的内容“撒谎”。如果需要更新的是关于类的数据,那么您应该有另一种存储该数据的方法。mef元数据不是一个数据库。谢谢李更新你的答案,但我认为你在分析一些不适用于我的情况的东西。我在元数据中有一个int属性,我只用于更新,“过滤器”由其他属性组成。此int属性仅用于更新显示,而无需加载整个零件。我想知道是否有可能在不重新加载所有部分的情况下更新一个属性,不要担心“撒谎”。我很感激你在回答问题时所做的一切努力,正因为如此,我投票支持你。问候。@Hannish好的,我看了你问题中的编辑,我认为你做错了。您不应该在运行时更新元数据中的属性