繁体   English   中英

如何使用 Visual Studio 2022 为解决方案中的所有项目全局管理 nuget 包?

[英]How to manage nuget packages globally for all projects in a solution using Visual Studio 2022?

我有一个使用 Visual Studio 2022 在 .NET 6.0 中创建的解决方案,该解决方案有很多项目。

每个项目在 .csproj 文件中都有很多 nuget package 引用,如下所示。

是否可以在解决方案中的单个位置/全局管理所有 nuget 包(而不是针对每个项目)?

这将确保解决方案中的所有项目都使用相同版本的 package(相同 nuget 包的项目之间不再有版本冲突)。

在中心位置更新 package 将确保所有项目都引用相同的更新版本。 无需为每个项目更新 package。

谢谢你的帮助。

  <ItemGroup>
    <PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />
    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.20.0" />
    <PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="2.0.2" />
    <PackageReference Include="Microsoft.ApplicationInsights.Kubernetes.HostingStartup" Version="2.0.2" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.1" />
    <PackageReference Include="Microsoft.Azure.ServiceBus" Version="5.2.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.1">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="6.0.0" />
    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.14.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.1" />
    <PackageReference Include="System.Collections" Version="4.3.0" />
    <PackageReference Include="System.Runtime" Version="4.3.1" />
  </ItemGroup>

有几种方法可以做到这一点。 目前(在本次编辑时),只有 NuGet 的 Central Package 版本管理支持管理传递 package 依赖项。

手动,使用 a.targets 文件

拥有一个包含您引用的所有包的 .targets 文件,但使用<PackageReference Update=而不是Include= 将此包含在您的 Directory.Build.targets 文件中,以便在每个项目文件的末尾应用它。

最大的缺点是,任何时候将新的 PackageReference 添加到任何项目时,您还需要记住更新 .targets 文件以包含更新 package 版本的条目。

这将确保您的所有<PackageReference>条目将统一为相同的版本。 但是,它不会影响传递引用,即如果您有 Project1 -> Package1 -> Package2,但只有 Package1 的 PackageReference,您将无法影响 Package2 的引用版本。 如果 Project2 -> Package2 的版本与 Package1 引用的版本不同,这可能会产生冲突。

使用中央 Package 版本 MSBuild SDK (CPV)

手动过程可能容易出错,因此有一个第 3 方 SDK 可以帮助使过程更顺畅。 您可以在Central Package 版本中找到它。 这也提供了强制用户不要在项目中指定版本(因为他们应该使用中央版本来代替。)因此它将比使用手动技术更加一致。

这也不能以任何方式解决传递依赖问题。

使用 Nuget 中央 Package 版本管理(CPVM)

这是 NuGet 团队对该问题的解决方案。 这篇博文对此进行了解释,或者您可以在集中管理 NuGet package 版本中找到原始文档。

在您的根文件夹中有一个名为 Directory.Packages.props 的文件,并通过添加以下内容启用该功能:

  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>

现在,与 CPV SDK 类似,您应该从<PackageReference>元素中删除所有版本,并将它们放在 Directory.Packages.props 文件中的<PackageVersion>元素中。 如果您需要覆盖一个版本,有两种方法:

  1. <PackageReference>项上,添加VersionOveride=1.2.3.4属性。
  2. 在 .csproj 中添加<PackageVersion Update="PackageName" Version="DifferentVersion" /> (这是因为 Directory.Packages.props 是通过 .NET SDKs.props 文件导入的,该文件是在评估 .csproj 的内容之前) .

这本身对传递引用没有帮助。 您还可以添加<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>以启用传递包的固定。 这基本上做的是确定您的任何直接或间接(传递)PackageReferences是否具有匹配的PackageVersion,如果是,它会促进它,就好像它是一个直接引用(意味着任何依赖它的东西也将获得固定版本) . 传递固定支持至少需要 NuGet 6.2、VS 2022 17.2 或 .NET SDK 6.0.300。

您可以将 class 库项目添加到您的解决方案中,其中包含对其他项目的所有包和引用。

对于 class 库项目:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
 <ItemGroup>
    ALL SHARED PACKAGE YOU WHANT
  </ItemGroup>
</Project>

在您的项目中添加此行

<ItemGroup>
    <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" />
</ItemGroup>

提到了新的 CPM 功能,但我想我也会包含一个完整的示例。

您可以使用 nuget 的新“中央 Package 管理”功能。

示例问题:

假设您有多个项目的 monorepo(即 VS“解决方案”或 VSCode“工作区”)。

ProjectA.csproj

<ItemGroup>
  <PackageReference Include="Foo.Bar.Baz" Version="1.0.0" />
  <PackageReference Include="Spam.Ham.Eggs" Version="4.0.0" />
</ItemGroup>

ProjectB.csproj

<ItemGroup>
  <PackageReference Include="Foo.Bar.Qux" Version="1.2.3" />
  <PackageReference Include="Spam.Ham.Eggs" Version="4.5.6" />
</ItemGroup>

有些项目相同,而有些项目不同。 而且您需要记住保持版本同步 - 该示例表明您忘记了这样做!

第 1 步:删除版本

ProjectA.csproj

<ItemGroup>
  <PackageReference Include="Foo.Bar.Baz" />
  <PackageReference Include="Spam.Ham.Eggs" />
</ItemGroup>

ProjectB.csproj

<ItemGroup>
  <PackageReference Include="Foo.Bar.Qux" />
  <PackageReference Include="Spam.Ham.Eggs" Version="4.0.0" />  <!-- note version override for this project -->
</ItemGroup>

第 2 步:将名为Directory.Packages.props的文件添加到您的存储库的根目录

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <!-- use 'PackageVersion' rather than 'PackageReference' -->
    <PackageVersion Include="Foo.Bar.Baz" Version="1.2.3" />
    <PackageVersion Include="Foo.Bar.Qux" Version="1.2.3" />
    <PackageVersion Include="Spam.Ham.Eggs" Version="4.5.6" />
  </ItemGroup>
</Project>

第三步:恢复

对于每个项目:

  • 清除构建 output: dotnet clean
  • 恢复包: dotnet restore

您的所有项目现在都将使用您在配置文件中指定的版本。

还有更多选项,例如版本覆盖和传递依赖固定 - 阅读文档了解更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM