项目A使用log4net 1.2.13.0
,并依赖于使用log4net 1.2.11.0
的图书馆B.如果我执行Package Manager Console> 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>
我认为这个必需才能完成构建。但是构建成功也没有重定向。这是我在构建日志中看到的(详细程度设置为详细):
统一主要参考&#34; log4net,版本= 1.2.13.0,Culture = neutral,PublicKeyToken = 669e0ddf0bb1aa2a&#34;。 使用此版本而不是原始版本&#34; 1.2.11.0&#34;在&#34; C:\ Users \ vorou \ code \ ConsoleApplication1 \ packages \ LibraryB.dll&#34;因为AutoUnify是真的&#39;。
AutoUnify的全部内容是什么?哪个更好,即在.config中有明确的重定向是否有任何优势?
此外,我记得,在某些情况下,您必需添加绑定重定向。否则应用程序将在运行时爆炸。这些案例是什么以及为什么AutoUnify
魔法不适合他们?
UPD 以下是MSDN关于AutoUnify
的摘录:
此参数用于构建程序集,例如DLL,它们不能具有正常的App.Config文件。 如果为true,则会自动将生成的依赖关系图视为传递给AppConfigFile参数的App.Config文件。此虚拟App.Config文件具有每个冲突的程序集集的bindingRedirect条目,以便选择最高版本程序集。这样做的结果是永远不会有关于冲突组件的警告,因为每个冲突都将得到解决。
看起来像.config中的重定向在我的情况下不起任何作用。问题是图书馆B无法满足它的依赖性,而AutoUnify
通过“假装有绑定重定向”规则来解决它。
答案 0 :(得分:21)
版本控制是一个很大的话题,不能在单个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所做的。没有什么比这更复杂,它选择了更高的版本。