【发布时间】:2020-01-08 13:10:35
【问题描述】:
我在加载 DLL 及其引用时遇到问题。场景是这样的:
我有一个 C# 库项目(我们称之为“A”),它引用了另一个 C# 库项目(我们称之为“B”)。这两个项目的 Dll 都存储在 Azure Blob 存储中,但这在现实中是无关紧要的。
作为我项目的一部分,我使用的是XslCompiledTransform.Transform。使用Assembly.Load加载dll A后,我再次使用Assembly.Load加载dll B。
问题是,在执行Transform 方法后,我一直收到一个错误,即找不到dll B,即使在我调用AppDomain.CurrentDomain.GetAssemblies(); 时它仍然存在
请注意,如果我从 A 中删除 B 的依赖关系,一切正常,因此我们可以确保仅使用 dll A 的 Transform 正常工作。
FileNotFoundException: 无法加载文件或程序集 'xxx, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null' 或其之一 依赖关系。系统找不到指定的文件。
还有一件事,如果我将 dll B 添加到项目 Bin 文件夹中,那么它可以工作,但是我当然不能这样做,我只是为了证明它可以工作。
【问题讨论】:
-
您确定异常没有发生在另一个应用程序域中吗?您是否考虑过在应用程序域的
AssemblyResolve事件中处理程序集负载? -
Dll 必须即时加载。我不想详细介绍系统需要如何工作,因为在设计方面我几乎没有控制权。不确定您的第一条评论,但如最后所述,如果我在加载 A 和 B 的项目的 bin 中包含 dll B,一切都按预期工作。但这是我无法做到的,因为 dll 是随机的。
-
如何“随机”?使用动态加载时有很多限制。例如,您不能在同一个域中拥有两个名称相同但版本不同的程序集。
XslCompiledTransform还处理动态创建/加载的库,因此可能存在各种版本冲突,或者它可能使用不同的AppDomain来执行转换(纯推测)。您的评论也没有真正解决我在评论中所说的话:) -
您可以启用 FusionLog 以了解运行时如何查找程序集,但在这种情况下它可能不会有用。一般来说,你对程序集解析所做的任何奇怪的事情都会有点痛苦——很难调试,你需要很好地理解 .NET 运行时的工作原理以及所有这些。我真正可以建议您的是要格外小心,您正在谈论的程序集完全符合它们应该是的方式(例如,来自相同的构建等),并且永远没有名称/版本冲突。 .NET 不会两次加载相同的名称。
-
我至少会尝试在
AppDomain.AssemblyResolve事件中写出一些调试输出 - 它会让您了解正在加载哪些程序集以及何时加载,以及它是否真的在尝试(并且失败)您的域。
标签: c# reflection .net-assembly