解决同一程序集的2个或更多不同版本的引用

时间:2017-09-24 20:30:07

标签: .net dependencies version .net-assembly

我理解这个问题至少被问到了几十次,而且答案有很多变化,但是没有人费心去解释所有细节并涵盖一种或另一种方法的所有方面。我在谈论看起来像这样的着名警告

  

无法解决“Deep,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = f694e838567cfe72”和“Deep,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = f694e838567cfe72”之间的冲突。任意选择“Deep,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = f694e838567cfe72”。   考虑从版本“1.0.0.0”[D:\ Misc \ Drive \ Main \ trunk \ Application \ DependencyResearch \ Bin \ Middle1 \ Deep.dll]的app.config重新映射程序集“Deep,Culture = neutral,PublicKeyToken = f694e838567cfe72”版本“2.0.0.0”[D:\ Misc \ Drive \ Main \ trunk \ Application \ DependencyResearch \ Bin \ Middle2 \ Deep.dll]解决冲突并摆脱警告。

您找到的第一个也是最受欢迎的答案就是将其添加到您的app.config

  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
     <dependentAssembly>
        <assemblyIdentity name="Deep" culture="neutral" publicKeyToken="f694e838567cfe72" />
        <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
     </dependentAssembly>
  </assemblyBinding>

通过添加此警告已经消失,这个想法非常明确。您指示框架在所有情况下使用版本2.0.0.0的Deep程序集,并且可能有效,但通常不会提及或仅仅假设它可能在非常有限的情况下工作。仅当最初引用版本1.0.0.0的所有代码仅调用那些在版本2.0.0.0中未更改签名且内部功能不会改变的方法时;否则你将面临一个不可预测的应用程序行为,其中任何部分之前可能会发生错误或异常。

下一个流行的答案只是将其添加到您的app.config

  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
     <dependentAssembly>
        <assemblyIdentity name="Deep" culture="neutral" publicKeyToken="f694e838567cfe72" />
        <codeBase version="1.0.0.0" href="Deep1\Deep.dll" />
        <codeBase version="2.0.0.0" href="Deep.dll" />
     </dependentAssembly>
  </assemblyBinding>

然而,添加此功能并不会删除我开始提问的警告。此外,这种方法在应用的可靠性和稳定性方面要好得多。使用版本1.0.0.0的所有代码都继续使用该版本,使用版本2.0.0.0的所有代码继续使用该版本。我真的不喜欢这个解决方案是警告消息仍然显示在每个构建中。这是否意味着冲突没有完全解决?为什么?或者只是编译器不理解冲突实际解决了?在我的构建中发出警告让我担心。

GAC被多次提到,但这不是一个选择。 GAC本身存在的问题多于它可以解决的问题。

如上所述,很明显唯一正确的解决方案是引用同一程序集的所有版本以确保代码的所有部分的稳定性。如果这是真的,有一个简单的解决方案吗?有没有办法告诉编译器总是将所有引用的程序集添加到目标二进制文件夹,将冲突的程序集放在不同的文件夹中,使用版本号作为名称或重命名程序集将名称添加到名称?

是否有一篇好文章详细解释了这个问题,所有可能的解决方案,它们的优点和缺点?

0 个答案:

没有答案