为什么我的 MEF 部分对插件主机不可见? [英] Why is my MEF part not visible to plugin hosts?

查看:65
本文介绍了为什么我的 MEF 部分对插件主机不可见?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a small class that performs a data import from a client. Each client has their own version of this class, so it is an MEF plugged in part:

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

然而,当我尝试导入插件时,如下所示:

Yet when I try and import the plugin, like so:

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

生成的目录有 1 个文件和 0 个零件,但零件在文件中.我已经通过 dotPeek 进行了检查.

The resultant catalog has 1 file and 0 parts, yet the part is in the file. I've checked with dotPeek.

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

What could cause the host to not see the exported part? Another tiny test host I wrote also imports the plugin assembly and it sees the part fine.

推荐答案

那可能是因为程序集没有加载.

That is probably because the assembly is not loaded.

我将描述调用 DirectoryCatalog

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

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

Internall the method Initialize is called and that does basically two things. It enumerates the *.dll files and after that it calls Assembly.Load on all of them.
When Initialize is finished the collections LoadedFiles and Parts are hopefully populated.

属性 LoadedFiles 误导了调试工作,因为在该集合中有一个文件并不意味着程序集确实被加载,它只告诉一个或多个名为*.dll"的文件在该文件夹中找到的位置.所以 LoadedFiles 最好被认为是 FoundFiles.

The property LoadedFiles is misguiding the debug effort because having a file in that collection doesn't mean the Assembly did actually get loaded, it only tells that one or more files named '*.dll' where found in that folder. So LoadedFiles is better thought of as FoundFiles.

收集LoadedFiles 后,实际加载假定的程序集.每个找到的文件都被送入 Assembly.Load.每当此操作失败时,Parts 集合中将没有任何类型.

After the LoadedFiles are collected the actually loading of the assumed assemblies take place. Every found file is fed into Assembly.Load. Whenever this fails you'll end up with no types in the Parts collection.

我通过让一个 x86 控制台应用程序尝试加载具有我的 Export 类型的 x64 dll 重现了您的情况.由于这些是简单的融合问题,我使用了 Fusion Log查看器进行诊断.我的场景显示以下错误:

I've reproduced your situation by having an x86 console app trying to load an x64 dll having my Export types. As these are simple fusion issue's I used the Fusion Log Viewer to diagnose. My scenario showed the following error:

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

The operation failed. Bind result: hr = 0x8007000b. An attempt was made to load a program with an incorrect format.

在文档中给出了不加载程序集的 3 个主要原因:

In the documentation 3 main reasons are given for not loading asemblies:

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

不知道您的主机应用程序/应用程序域看起来如何,您可能需要 这篇文章 描述了如何诊断融合问题.它适用于框架的 v2,但有些可能仍然相关.以下段落摘自该文章:

Not knowing how your host application/appdomain looks like you might need this article that describes how to diagnose fusion issues. It is for v2 of the framework but some might still be relevant. The following paragraphs are an excerpt from that article:

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

For BadImageFormatException:
Try running peverify.exe on the file.

对于安全异常:
您需要执行权限才能加载任何程序集.

For SecurityException:
You need Execute permission for loading any assembly.

对于 FileLoadException:

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

  • For an "Access is denied" message (for hresult E_ACCESSDENIED, 0x80070005):
    Run tlist -m on the file to see if another process has the file locked and without share-read access.

对于名为 [yourAssembly] 的定位程序集的清单定义与程序集引用不匹配"消息(对于 hresult FUSION_E_REF_DEF_MISMATCH,0x80131040):
Fusion 日志将说明程序集引用的哪一部分与找到的内容不匹配.它将是程序集名称、文化、公钥(或令牌)或版本(如果找到的程序集是强命名的).

For a "The located assembly's manifest definition with name [yourAssembly] does not match the assembly reference" message (for hresult FUSION_E_REF_DEF_MISMATCH, 0x80131040):
The Fusion log will say which part of the assembly reference failed to match what was found. It will be the assembly name, culture, public key (or token) or version (if the found assembly was strongly-named).

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

For "Unverifiable image [yourAssembly] can not be run" or "Can not run executable [yourAssembly] because it contains relocations" messages (for hresult COR_E_FIXUPSINEXE, 0x80131019):
That image must be run as the process exe or else be compiled as a dll. This is because MC++ has made optimizations for you in your image, based on the assumption that it will be the process exe.

这篇关于为什么我的 MEF 部分对插件主机不可见?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆