22

Newtonsoft.Json 发布了具有相同强名称的不兼容版本,仅更改了文件版本。

根据MSDN

具有相同强名称的程序集应该相同。

因此,如果我们无法控制的其他应用程序将不同版本的 Newtonsoft.Json.dll 放入 GAC,我们的应用程序就会中断。

有什么方法可以强制 .NET 加载我们需要的特定版本?

更新:

让我更深入地解释这个问题:

据我所知,在 .NET 中,在 CLR 尝试解析程序集并失败之前,没有解析程序集的机制。

只有 AppDomain.AssemblyResolve 事件,它仅在程序集未解析时触发。通常这就足够了。

但是在 Newtonsoft.Json 的情况下,它不会无法解析程序集,但它只是加载了错误的程序集。

发生这种情况是因为 Newtonsoft.Json 发布了具有相同强名称的不兼容版本。

例子:

假设我们的应用程序针对 NJdll 编译(程序集版本1.0,文件版本 1.0)

然后一些其他应用程序,将相同dll的其他不兼容版本放入GAC NJdll(程序集版本1.0,文件版本1.1

因为它们只更改文件版本而不更改程序集版本,所以这两个程序集具有相同的强名称。

因此,对于我们试图解析 NJdll(程序集版本 1.0)的应用程序 .NET,它会在 GAC 中看到 dll 并加载它。(因为 .NET 总是更喜欢 GAC 中的程序集而不是“bin”文件夹中的程序集

但是加载的程序集是错误的。它的文件版本为 1.1,与版本 1.0 不兼容。

因为这两个程序集具有相同的程序集版本,所以 .NET 看不到它们之间的任何差异。但是当它实际上试图解析内部的某个类或成员时,它失败了,因为它在 1.1 版中被更改了。

整个应用程序因不可预知的错误而失败。

最糟糕的是,即使我的应用程序没有将 newtonsoft.json.dll 放入 GAC,我无法控制的其他一些应用程序会将不同版本的 newtonsoft.json.dll 放入 GAC - 我的应用程序会因不可预知而中断例外。

所以我的问题是,在.NET 加载错误的程序集之前,我可以先加载正确的程序集吗?

更新

https://github.com/JamesNK/Newtonsoft.Json/issues/615 https://github.com/JamesNK/Newtonsoft.Json/issues/1001

与此问题有关的问题已通过评论结束,该评论表明 Newtonsoft.Json 的作者不了解 .NET 版本控制以及为什么这很重要。

4

1 回答 1

3

程序集加载器将仅探测丢失的程序集,即尚未加载的程序集。如果将 DLL 部署到应用程序安装文件夹,然后在应用程序启动时显式加载它,则程序集加载器将不会尝试从 GAC 再次加载它。

Assembly.LoadFrom您可以使用该方法显式加载程序集。

有关详细信息,请参阅https://msdn.microsoft.com/en-us/library/dd153782(v=vs.110).aspx

于 2016-09-29T00:24:22.203 回答