程序集加载问题 ("Could not load type")

Assembly loading Problem ("Could not load type")

我在使用两个不同的 WebSocket 引用时遇到问题。一个是较新的版本,实现了一个名为“SocketIO”的扩展 WebSocket,另一个只是标准的 RFC6544 WebSocket。较新的 'inherited' 或多或少是旧版本的一部分,但到今天它们并不真正兼容。由于各种原因,我需要能够在项目中使用两者。

现在,如果我单独试用它们,它们工作得很好。

如果我在一个项目中一起尝试它们,我会在较新的项目中抛出异常:

"Could not load type ... from Assembly.... Version = ... etc".

它显然在 other Websocket 引用的程序集中搜索其类型,但找不到它。

他们不共享相同的 class 名称,例如显式命名引用没有效果,也没有 VisualStudio 标记的公开冲突。

我用谷歌搜索但没能找到解决方案,例如如何准确地告诉程序在哪里寻找较新的程序集。

更新:

所以我查看了 SocketIO 清单,确切的问题是:

  1. SocketIO 引用旧版本的 WebSocket4Net

  2. 当前版本的 WebSocket4Net 缺少其中一些旧类型

  3. 问题:SocketIO 在没有新的或旧的 WebSocket4Net 程序集的情况下工作很好 - 但一旦引用可用,它就会解析该程序集并抛出找不到特定过时类型的错误。

在我为此烧了 4 小时之后,我通过使用不同的辅助 WebSocket(WebSocketSharp 而不是 WebSocket4Net)规避了这个问题;问题消失了,因为 WebSocketSharp 没有像 Websocket4Net 那样与 SocketIO 共享 present/past 代码。

这背后的核心问题虽然没有解决,但我估计这是一个边缘问题,例如明确分配或忽略特定类型的给定外部程序集。

OP:

i use two different WebSocket references...Now if i try them out alone, they work just fine.
If i try them in a project together, i get at the newer one throw an exception

我怀疑 WebSocket4Net assemblys 都不是 strong-named (SN),如果是这样的话 .NET not 允许您将两个或多个非强名称程序集加载到同一个 App Domain ,即使这些程序集具有不同的版本号.

SNing 提供了许多好处,特别是对于 CAS 场景和将程序集放入 GAC。一些开源人士不喜欢 SN,但我发现他们的恐惧是基于错误的信念,即 SN 是某种形式的软件保护。他们应该参考 Authenticode.

MSDN:(我强调)

Do not rely on strong names for security. They provide a unique identity only.

.NET 程序集默认没有 SN,请参阅 Visual Studio (VS) 中的 Signing 选项卡。

SN 程序集基于四 (4) 个属性:

  1. 纯文本名称。例如MyCoolControls
  2. 版本号。例如3.2.7.0
  3. 文化信息。例如en-AU
  4. Public密钥和数字签名

这不仅跨版本而且在该版本内的跨文化中唯一地定义程序集。

解决方案

要避免此问题,您有两种选择:

  1. SN 程序集: 从编码的角度来看最简单的编码是SN 两个WebSocket4Net 程序集。如果您可以获得源代码(假设它是开源的),那么您可以使用 SN 步骤编译它会更容易。否则结帐 this page。完成后,您只需确保您的版本 X C# 代码具有完整的名称space 对程序集 X 的引用和版本 Y 对程序集 Y 的引用。否则,您所指的是哪个版本的编译器。

  2. 创建子应用程序域:更高级的步骤要求您为每个弱命名的 WebSocket4Net 版本创建一个子 AppDomain .然后将特定于 WebSocket4Net 版本的代码放在 AppDomain 中。这允许您在您的进程中同时将两个原始程序集加载到它们自己的 space 中而不会发生冲突。此选项不需要WebSocket4Net

    进行任何修改

程序集清单

就我个人而言,我尽量避免汇编清单和他们喜欢的汇编重定向。它们有点像 hack,可能会导致意外的运行时问题。他们没有解决问题的根源。调试程序集探测和加载顺序从来都不是一件有趣的事。

更多