我什么时候需要使用绑定重定向?

16

项目A使用log4net 1.2.13.0,并依赖于Library B,该库使用log4net 1.2.11.0。如果我执行Package Manager控制台> Add-BindingRedirect,我会在app.config中得到正确的绑定重定向:

  <dependentAssembly>
    <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-1.2.13.0" newVersion="1.2.13.0" />
  </dependentAssembly>

我以为这个重定向是构建必要的步骤,但是在没有重定向的情况下也可以成功构建。下面是日志详细信息:

“log4net, Version=1.2.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a”被统一为主引用。 在“C:\Users\vorou\code\ConsoleApplication1\packages\LibraryB.dll”中使用此版本,而不使用原始版本“1.2.11.0”,因为AutoUnify设置为'true'。

什么是AutoUnify? 显式重定向在.config文件中更好吗?

另外,我记得有些情况下您需要添加绑定重定向,否则应用程序会在运行时崩溃。 这些情况是什么,为什么这种“AutoUnify”魔法对它们无效?


更新 这是来自MSDN的摘录,介绍了AutoUnify

此参数用于构建无法拥有正常App.Config文件的程序集,例如DLL。当值为true时,生成的依赖项图像会自动处理为如果将AppConfigFile参数传递给了App.Config文件。这个虚拟的App.Config文件对于每个冲突集合的程序集都有一个bindingRedirect条目,以选择最高版本的程序集。其结果是将不会有关于冲突程序集的警告,因为每个冲突都已经被解决。

看起来在我的情况下,.config文件中的重定向没有任何作用。问题在于Library B不能满足它的依赖关系,并且“AutoUnify”通过那个“假设存在绑定重定向”的规则解决了这个问题。

1个回答

36

版本控制是一个大题目,在单个SO帖子中无法充分阐述。 简而言之:

当您使用多个Nuget软件包并且它们具有公共依赖项(例如log4net或NewtonSoft.Json等非常常见的库,它们没有安装程序将程序集放入GAC时),需要进行这种调整。

问题在于,每个Nuget软件包很可能使用不同版本的这些核心支持库进行构建。 这样的软件包不太可能获得足够的更新以使其保持与最新版本的兼容性,软件包作者更喜欢使用他测试代码的版本。 因此,您很容易会在构建目录中找到一个程序集要求1.2.11.0,另一个程序集要求1.2.13.0

那是行不通的。 当加载程序集时,CLR要求精确版本匹配。 并且必须从构建目录加载它,不能依赖于GAC来提供它们。 DLL只能有一个副本,不可避免地,软件包库之一将获得错误的版本,导致程序崩溃。 你有一个问题,如果没有重新构建Nuget软件包,你无法解决它。

这就是绑定重定向所解决的问题。 它仅在运行时起作用,而不是构建时。 它告诉CLR:“如果它请求1.2.11.0,则只需加载1.2.13.0。或者更一般地说,使用此特定绑定重定向:“如果它请求任何低于1.2.13.0的版本”。问题解决了,不再崩溃。 希望软件包仍能与该新版本一起正常工作。通常情况下,当仅差修订号时,它们确实可以,但并没有硬性保证。

还需要做出的另一件事(在构建时发生)是选择哪个特定版本的库。 您想要1.2.11.0还是1.2.13.0? 这就是AutoUnify所做的。 没有什么非常复杂的东西,它选择更高版本。


4
如果我们有A -> C(v2.1)和B -> C(v2.2),为什么不将A和B的依赖关系视为它们自己的问题?(因为CLR等等...),但是为什么CLR要强制这样的约束呢?谢谢! 如果A指向C(v2.1),而B指向C(v2.2),为什么不将A和B的依赖关系视为它们各自的问题呢?这是因为CLR等工具会强制实施此约束。那么,为什么CLR要强制这种限制呢?谢谢! - Cristian E.
2
CLR没有这样的限制。如果你有两个名为C.dll的文件,那么只有一个地方可以放它们,以免彼此覆盖。不要使用它。 - Hans Passant
1
我在这方面缺乏知识,但为什么需要将 C 暴露在 A 和 B 之外呢?A 和 B 应该是独立/自包含的动态链接库(DLL)。(我并不是在争论,只是想更好地理解“为什么”)。感谢您的耐心。 - Cristian E.
2
毫無保證您的軟體在使用最新版本的依賴程式(1.2.13.0)時不會崩潰,因為Library B是專門針對版本1.2.11.0進行測試的。正如漢斯所說:“祈禱這個套件仍然能夠與那個更新的版本一起運作。”- 這意味著您自願且風險自負地接受版本衝突解決。+1 - sɐunıɔןɐqɐp

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