Newtonsoft Json.NET版本不兼容(DLL地狱)

时间:2015-07-24 11:06:28

标签: .net json.net versioning .net-assembly global-assembly-cache

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

根据MSDN

  

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

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

有没有办法强制.NET加载我们需要的特定版本?

更新

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

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

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

但是在使用Newtonsoft.Json 的情况下,它可以解决程序集,但它只是加载错误的。

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

示例:

让我们说我们的应用程序针对N.J.dll编译(程序集版本 1.0 ,文件版本1.0)

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

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

因此,对于我们的应用程序.NET尝试解析N.J.dll(程序集版本1.0),它会在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版本以及为什么这很重要。

1 个答案:

答案 0 :(得分:3)

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

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

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