如何解决.NET Dll Hell问题?

11

如何解决?

我有两个第三方程序集,它们都使用了NewtonSoftJson.dll。问题在于其中一个使用了较旧的3.x.x版本,另一个使用了4.5.x版本。因此,在运行时,至少有1个程序集会对另一个程序集进行投诉。

我该如何解决这个问题?我可以设置服务,但代码和环境目前还没有准备好。在给定的时间内进行太多重构也不安全。


这两个程序集是否在同一个目录下? - Sam Axe
这可能会有所帮助:http://blogs.msdn.com/b/abhinaba/archive/2005/11/30/498278.aspx - Oded
1
https://dev59.com/3XA75IYBdhLWcg3wrrNS - Oded
1
这不是针对Silverlight的,对吧?因为如果是的话,你可能会遇到麻烦:https://dev59.com/F2LVa4cB1Zd3GeqPtiiz - Chris Sinclair
4个回答

4

我曾经遇到过与Newtonsoft和另一个第三方库完全相同的问题。Newtonsoft v3.x和v4.x的问题在于新库现在带有公钥令牌。这使得程序集重定向解决方案无效; 但对于大多数其他情况来说,这是一个完全有效的解决方案。

最终我自己重新实现了第三方库。如果您可以访问第三方库的源代码,则始终可以使用较新的Newtonsoft DLL重新构建该库。如果任何方法签名发生更改,则可能需要进行微小更改。


1
遇到了同样的问题,下载了一个小应用程序(只有几KB),需要我没有的框架版本。要安装它,你必须自己搜索,这可能会导致沮丧(版本地狱)。这是一个小应用程序,但需要很多无用的东西。安装框架后,它需要更新(看起来像无尽的更新)。这不是非常用户友好和疯狂的应用部署方式。现在我明白为什么Windows那么庞大,也知道为什么世界上有那么多秃头男人。三思而后行,是否使用.NET开发您的产品。 - Codebeat

3
微软的文章"重定向程序集版本"提到:

以下示例展示如何将一个版本的myAssembly重定向到另一个版本,并关闭对mySecondAssembly的发布策略。

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="myAssembly"
          publicKeyToken="32ab4ba45e0a69a1"
          culture="en-us" />
        <!-- Assembly versions can be redirected in application, 
          publisher policy, or machine configuration files. -->
        <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
      <assemblyIdentity name="mySecondAssembly"
        publicKeyToken="32ab4ba45e0a69a1"
        culture="en-us" />
        <!-- Publisher policy can be set only in the application 
          configuration file. -->
        <publisherPolicy apply="no" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

2
你能演示一下如何做到每个依赖于不同版本的 NewtonSoftJson 的程序集都获取正确的版本吗? - Oded
@Oded:我不行。我现在没有时间去探索这个问题。也许这个周末可以。 - Sam Axe

2

通常情况下,您可以通过在应用程序/ web配置中进行配置来解决此问题。您可以使用探测元素来指定私有路径,并将两个版本放在不同的文件夹中:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2\subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>

另一种方法是使用程序集绑定重定向。但仅当您知道版本兼容时才有效。由于您没有直接使用它们,我不确定您是否知道,而出版商通过更改程序集版本已指示某些不兼容性。


1

最终使用反编译器,将项目添加到解决方案中,引用新的dll文件,修复错误并重新编译,指向最近添加的项目。

由于公钥令牌已更改,我无法使用程序集重定向。显然,编译其中一个被引用程序集时使用了不同的密钥。不得不采取更加激烈的措施。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接