【发布时间】:2010-12-22 23:49:07
【问题描述】:
今天收到这个错误让我感到非常惊讶,因为这是我以前从未遇到过的错误。代码中的一切看起来都不错,所以我做了一些搜索。之前的问题及其各自的答案没有帮助。
This one 在张贴者确保他的程序集引用一致时得到解决。我现在没有这个问题,因为我目前正在我的解决方案中引用另一个项目。
This one 在发帖人被指示使用 ImportMany 时已解决,但我已经在使用它(我认为也是正确的)尝试加载多个插件
This one 在发帖人意识到平台目标不匹配时解决。我已经完成了我的项目以确保所有内容都针对 x86。
这就是我想要做的。我有一个拥有与设备连接的插件。我可能还需要能够与另一个插件共享该连接。我认为最简洁的方法是创建一个接口,允许从属插件请求自己与设备的连接。我们就叫它IConnectionSharer吧。如果从属插件确实不需要需要借用这个连接并且有自己的,那么它应该使用自己的IConnectionSharer实现来连接到设备。
我的“主”插件(拥有设备连接的插件)实现了IConnectionSharer。它还通过 ExportAttribute 导出它。
我的“从属”插件程序集定义了一个类,该类还实现和导出IConnectionSharer。
当应用程序加载时,我的 slave 插件通过 MEF 枚举所有 IConnectionSharers 并将它们存储在 IEnumerable<IConnectionSharer> 中。这样做是这样的:
[ImportMany]
public IEnumerable<IConnectionSharer> AllSharedConnections { get; set; }
尼古拉斯让我出示我的Exports,所以他们来了。
“大师”插件:
[PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(Interface1))]
[Export(typeof(Interface2))]
[Export(typeof(Interface3))]
[Export(typeof(IConnectionSharer))]
public partial class MasterPlugin : Interface1, Interface2, Interface3, IConnectionSharer
{
...
}
“从”插件:
[PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(Interface1))]
public class SlavePlugin : Interface1
{
private Model _model { get; set; }
private ViewModel _viewmodel { get; set; }
[ImportingConstructor]
public SlavePlugin( [Import] Model model)
{
_model = model;
_viewmodel = new ViewModel( model);
}
}
型号:
[Export(typeof(Model))]
public class Model
{
[ImportMany(typeof(IConnectionSharer))]
private IEnumerable<IConnectionSharer> AllSharedConnections { get; set; }
...
}
“从”插件内部的 IConnectionSharer 实现:
[Export(typeof(IConnectionSharer))]
public class PrivateConnection : IConnectionSharer
{
...
}
但在部件组合过程中,我收到错误导出“Company.MasterPlugin (ContractName="IConnectionSharer")' is notassignable to type 'IConnectionSharer'。
错误消息本身似乎很清楚——就好像 MEF 认为我的主插件没有从 IConnectionSharer 继承......但确实如此!谁能建议进一步的调试策略?我将开始单步调试 MEF 源的痛苦过程。
更新
这是一个有趣的线索——如果在清除我的输出文件夹并重建解决方案之后,我删除“主”插件(这样“从”插件将使用它自己的 IConnectionSharer对象),我的应用程序加载得很好,我的从属插件也按预期运行。如果我将主插件放回 plugins 文件夹,我会再次遇到 MEF 组合问题。
我还想尝试使用 Lazy 实例化来查看是否有任何效果。结果有点令人吃惊。 MEF 抱怨此错误:无法填充集合“AllSharedConnections”,因为它没有实现 ICollection 或者是只读的。如果集合不是 IEnumerable<T> 或 T[],它必须实现 ICollection 并且可以预先初始化或使用默认构造函数写入。
哈?显然 AllSharedConnections 是IEnumerable<T>,那么为什么 MEF 会抱怨呢?
【问题讨论】:
-
您使用的是哪种目录?什么样的应用程序?您是否尝试过从主机引用插件程序集?你的出口是什么样的? - hth,尼克
-
我使用的是
AggregateCatalog,因为我需要查看几个文件夹(两个DirectoryCatalog)。有一次我还必须添加一个AssemblyCatalog,因为没有它,由于某种原因我无法导入我的 ViewModel(不确定为什么 DirectoryCatalog 不会覆盖它,因为可执行文件在目录中)。我将使用导出更新上面的代码。我没有尝试硬引用插件程序集,因为我总是从 MEF 开始并且只想让它工作。不过我可以试试。谢谢!
标签: c# wpf visual-studio-2010 .net-4.0 mef