为什么插件主机看不到我的MEF部分?

时间:2013-12-30 12:58:07

标签: .net mef

我有一个小类,可以从客户端执行数据导入。每个客户端都有自己的此类版本,因此它是一个插入部分的MEF:

[Export(typeof(IXTImportEmployeePrePlugin))]
public class PreEmployeeImport : XTImportEmployeePrePlugin

然而,当我尝试导入插件时,就像这样:

var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory + PluginDir);

结果目录有1个文件和0个部分,但该部分在文件中。我用dotPeek检查过。

什么可能导致主机看不到导出的部分?我写的另一个小测试主机也导入了插件程序集,它看到该部分很好。

1 个答案:

答案 0 :(得分:2)

这可能是因为未加载程序集。

我将描述一旦调用DirectoryCatalog

的构造函数后发生的过程
var catalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory + "second");

Internall调用方法Initialize,基本上做了两件事。它枚举* .dll文件,然后在所有文件上调用Assembly.Load 完成Initialize后,希望可以填充集合LoadedFilesParts

属性LoadedFiles误导了调试工作,因为在该集合中有一个文件并不意味着Assembly实际上已经加载了,它只告诉一个或多个名为'* .dll'的文件在哪里找到那个文件夹。因此,LoadedFiles最好被认为是FoundFiles

收集LoadedFiles后,会发生假定组件的实际加载。每个找到的文件都被输入Assembly.Load。每当此失败时,您最终都不会在Parts集合中找到任何类型。

我通过让x86控制台应用尝试加载具有Export类型的x64 dll来重现您的情况。由于这些是简单的融合问题,我使用Fusion Log Viewer进行诊断。我的方案显示以下错误:

  

操作失败。绑定结果:hr = 0x8007000b。一次尝试   用于加载格式不正确的程序。

在文档3中,主要原因是没有加载组件:

  • 该部分位于EXE文件中。默认DirectoryCatalog仅从DLL文件中读取。您可以使用DirectoryCatalog通过使用适当的搜索模式创建其他文件来读取。
  • 零件的装配缺少参考。使用的程序集必须能够从搜索路径加载其引用,通常是从它们自己的目录或从全局程序集缓存加载。
  • 部件的程序集针对不同的CPU类型。 MEF不会加载针对错误CPU类型的程序集。

不知道主机应用程序/应用程序域的外观,您可能需要this article来描述如何诊断融合问题。这是框架的v2,但有些可能仍然相关。以下段落摘自该文章:

对于BadImageFormatException:
尝试在该文件上运行peverify.exe。

对于SecurityException:
您需要执行权限才能加载任何程序集。

For FileLoadException:

  • 对于“访问被拒绝”消息(对于hresult E_ACCESSDENIED,0x80070005):
    在文件上运行tlist -m以查看另一个进程是否已锁定文件且没有共享读取访问权限。

  • 对于“找到的程序集的清单定义名称[yourAssembly]与程序集引用”消息不匹配(对于hresult FUSION_E_REF_DEF_MISMATCH,0x80131040):
    Fusion日志将说明程序集引用的哪个部分与找到的内容不匹配。它将是程序集名称,区域性,公钥(或令牌)或版本(如果找到的程序集具有强名称)。

  • 对于“无法验证的图像[yourAssembly]无法运行”或“无法运行可执行文件[yourAssembly],因为它包含重定位”消息(对于hresult COR_E_FIXUPSINEXE,0x80131019):
    该映像必须作为进程exe运行,否则编译为dll。这是因为MC ++已经在您的图像中对您进行了优化,基于它将成为进程exe的假设。