【问题标题】:How to prevent upgrade of references when using NuGet使用 NuGet 时如何防止引用升级
【发布时间】:2022-01-26 19:19:24
【问题描述】:

我有一个简单参考的 .csproj 项目。

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
...
  <ItemGroup>
    <Reference Include="System.Net.Http" />
  </ItemGroup>
...

我还有用于 NuGet 参考的 project.json

{
  "dependencies": {
    "SomePackage": "1.1.1-beta",
  },
  "runtimes": {
    "win": {}
  },
...

使用此设置可以正常工作。 但是最近“SomePackage”开始依赖另一个包,它通过一堆传递依赖依赖于 NETStandard.Library" version="1.6.1"

<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <id>Microsoft.Extensions.Configuration</id>
    <version>1.1.0</version>
    <dependencies>
      <group targetFramework=".NETStandard1.1">
        <dependency id="Microsoft.Extensions.Configuration.Abstractions" version="1.1.0" />
        <dependency id="NETStandard.Library" version="1.6.1" />
      </group>
    </dependencies>
  </metadata>
</package> 

NETStandard.Library 依赖于较新版本的 System.Net.Http 4.1.0.0

当我编译项目时,程序集开始直接引用新版本 System.Net.Http。

然后它当然开始在运行时请求这个 dll。

我针对 .net 4.6.2 进行编译,Microsoft.Extensions.Configuration 针对 .Net 标准 1.1 进行编译。所以它应该在安装了 4.6.2 的机器上工作。 但是4.6.2不包含这个新版本的System.Net.Http 4.1.0.0

所以我的问题是如何阻止 NuGet 和 MsBuild 将我的程序集的直接引用升级到我使用的包的传递依赖项的版本?

谢谢。

【问题讨论】:

  • 我发现这是由于 MsBuild 中的 AutoUnify 功能所致。但关于 AutoUnify 的信息很少。并且不清楚如何关闭它。

标签: .net msbuild nuget


【解决方案1】:

如果您担心它唯一的程序集引用,那么AutoUnifyAssemblyReferences 就是您的答案。如果您使用的是 Visual Studio 2017,请转到路径 C:\Program Files (x86)\MSBuild\14.0\Bin(或安装相应 MSBuild 版本的相应路径)并搜索 Microsoft.CSharp.targets 文件。这是 Visual Studio 使用的目标文件,因此是 MSBuild 在构建解决方案时使用的目标文件。在此文件中,您可以添加以下标记:

   <AutoUnifyAssemblyReferences>false</AutoUnifyAssemblyReferences>

在进行这些更改后保存文件。所有后续构建都将阻止自动组装版本升级。 警告:此设置将适用于您使用该特定版本的 Visual Studio / MSBuild 构建的所有项目。问题解决后,您可以恢复到目标文件的原始版本。

为了防止 NuGet 自动升级,您可以参考解决此问题的 this stack-overflow 帖子。

编辑:如果您想在项目级别进行控制,请按照以下方式进行。在您的csproj 文件中,标识带有&lt;Target&gt; 标记的部分(可能会被注释),然后将其修改如下:

   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" >
      <Target Name="BeforeResolveReference">
        <AutoUnifyAssemblyReferences>false</AutoUnifyAssemblyReferences>
      </Target>
   </Import>

我自己从未尝试过,但这在理论上应该可行。 Here 是所有目标名称的链接,您可以覆盖它以将 AutoUnifyAssemblyReferences 标志设置为 false。

【讨论】:

  • 感谢您的回答。太床了,这无法在项目级别上进行控制。在构建机器上修改文件会干扰其他构建,这几乎是 VSTS 代理的阻碍。
  • 也可以在项目级别控制,但我自己没试过。用步骤更新了答案。
  • 给出的项目级解决方案存在语法错误。我认为 XML 应该是:&lt;Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /&gt; &lt;Target Name="BeforeResolveReference"&gt; &lt;PropertyGroup&gt; &lt;AutoUnifyAssemblyReferences&gt;false&lt;/AutoUnifyAssemblyReferences&gt; &lt;/PropertyGroup&gt; &lt;/Target&gt;
  • 在给定的每个项目的原始 XML sn-p 中肯定存在错误,因为显示的 Import 标记是自动关闭的,但是还有一个 Import 关闭标记。如果我停止 Import 标签的自动关闭,我会收到一个错误,即 Target 标签不能嵌套在 Import 标签中。我遵循了 vyrp 的代码 sn-p 并允许我在 Visual Studio 中加载项目文件(因此 Target 是 Import 标记的对等标记,而不是子标记),但是在来自“ Unified Dependency”处理说它正在将依赖项更改为 Unsafe v5.0.0.0。
猜你喜欢
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2017-07-22
  • 2015-12-16
相关资源
最近更新 更多