每个app.config都被添加了Binding Redirect,该如何处理?

10

我在一个解决方案文件中有20个项目。其中1个项目是标准库项目,其他19个项目都引用它。

大约一年前,我们添加了一个新的NuGet软件包,我们称之为Package A版本5.0.0.0。它有许多文件,当我们编译时会将这些文件传输到各个地方,但最终我们处理了它。我们将该软件包添加到了我们的标准库项目中(其他19个项目引用了该项目)。

我对NuGet还不熟悉(所以可能做错了什么),因此我创建了一个新软件包作为Package A的帮助程序。我已经设置好了所有内容,使得这个帮助程序依赖于Package A的版本3.0.0.0到5.0.0.0(所以它可以适用于那些低于我们版本的人)。我们把这个新软件包叫做Package A helper

我安装了Package A helper,一切都按照预期工作。我去进行拉取请求,我们解决方案中的每个app.config现在都有了

<runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
              <dependentAssembly>
                      <assemblyIdentity name="Package.A" publicKeyToken="8FC3CCAD86" culture="neutral"/>
                      <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0"/>
              </dependentAssembly>
      </assemblyBinding>
</runtime>

没有添加绑定重定向时,它可以正常编译,但Visual Studio会发出警告。这是为什么?我的经理现在不允许我合并代码,因为它会在app.config中添加太多噪音,并且过于依赖Package A。

为什么添加一个依赖于Package A的NuGet包后,主要依赖项在安装Package A Helper之前已经满足了,为什么还需要这个新的绑定重定向?

为什么它显示0.0.0.0-5.0.0.0,而我在nuget包和package.config中指定了3.0.0.0-5.0.0.0?

更新:

当我使用对Package A版本5.0.0.0的引用构建Package A Helper时,所有的绑定重定向都不会自动填充到每个app.config中,而是会生成警告。我最初使用3.0.0.0构建它,因为我认为使用最低的依赖项进行构建是最好的。问题仍然存在,因为Visual Studio仍然发出警告,并建议创建绑定重定向。

No way to resolve conflict between "Package A, Version=5.0.0.0, Culture=neutral, PublicKeyToken=83hfhsd33" and "Package A, Version=3.0.0.0, Culture=neutral, PublicKeyToken=83hfhsd33". Choosing "Package A, Version=5.0.0.0, Culture=neutral, PublicKeyToken=83hfhsd33" arbitrarily.
Consider app.config remapping of assembly "Package A, Culture=neutral, PublicKeyToken=83hfhsd33" from Version "3.0.0.0" [] to Version "5.0.0.0" [path to Package A dll] to solve conflict and get rid of warning.

我只需要把我的NuGet包依赖从3.0.0.0更改为5.0.0.0,取消在我的packages.config中的allowedVersions="[3,6)",这样就可以允许使用5.0.0.0并且不需要任何警告或bindingRedirects。我不想降低我的NuGet包的有用性和向后兼容性,但同时也想要避免出现任何问题。

更新2:将引用属性中的Copy Local设置为False实际上解决了我的问题,但我不知道为什么。


请问您能否提供一下您所看到的警告信息的详细内容? - Simon MᶜKenzie
@SimonMᶜKenzie 他们已被添加。 - LearningJrDev
1个回答

7
我最初使用3.0.0.0版本构建它,因为我认为那是最好的选择...这就是问题开始的地方。现在你的解决方案依赖于两个不同版本的A.dll,其中一个会覆盖另一个。 A.dll的哪个版本最终被复制到bin\Debug是随机的,取决于最后构建的项目。这样做不会有好结果,解决方案注定无法执行。如果是A-helper.dll中的代码,当5.0.0.0版本被复制时,它将失败。或者是任何其他使用A.dll的项目中的代码,当3.0.0.0版本被复制时,它将失败。最终结果是解决方案将始终失败。
所以你看到了构建系统正在处理这个问题。它注意到了不一致性,并选择其中一个版本胜出。它选择了5.0.0.0,这是正确的选择。它还修改了app.config文件,添加了bindingRedirect,因此请求加载3.0.0.0版本的代码实际上会获取5.0.0.0版本。如果你使版本5与版本3足够兼容,那么这可能会起作用。或者不行,主要版本号增加两次通常会带来麻烦。在测试时您会发现。
因此,在引用属性中设置“复制本地”为False实际上没有解决我的问题,你只是阻止了构建系统假定它应该为您解决此问题。由于它不再需要复制DLL,因此它猜测您将在GAC中安装程序集,以便两个版本可以共存。也许您确实这样做了,但通常在开发机器上这样做非常不明智。很少有老板和团队成员会喜欢这种解决方案,因为需要额外的安装步骤。
所以有两件基本的事情你可以做:
1. 让构建系统解决这个问题。就像它所做的那样,它正确地解决了问题,你的解决方案将起作用。如果版本5与版本3足够兼容,则A-helper.dll中的代码甚至可以正确执行。如果老板不喜欢它,那么你当然必须放弃这个方案并做:
2. 更改A-helper项目中对A版本5.0.0.0的引用。现在不存在任何不兼容性,唯一的A.dll适用于所有代码。考虑到你的要求,这是你的老板唯一会喜欢的解决方案。

最终我在 A helper 中使用版本 5 进行编译,然后添加了一个安装 powerscript,将复制本地设置为 false。这样就没有警告了(版本 3 和 5 也是错误的示例,真正的版本在同一主要版本中)。不过现在我很好奇,既然已经使用版本 5 编译了,我尝试使用版本 3 创建新项目,但无法工作,尽管我说它只需要 3+。这就是为什么我使用版本 3 进行编译,以便使用版本 3 的人可以使用该插件。 - LearningJrDev

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