Nuget 将多个项目打包到具有所有外部依赖项的单个 Nuget 包中

VJS*_*arp 2 msbuild nuget dotnet-cli

我希望从多个 .csproj 创建一个 nuget 包。

例如:我有两个 .csproj,其中之一依赖于其他外部包,例如 NewtonSoft。

dotnet new classlib -o ClassLibrary1
dotnet new classlib -o ClassLibrary2
cd ClassLibrary1
dotnet add package Newtonsoft.Json
Run Code Online (Sandbox Code Playgroud)

我希望发布一个包含 ClassLibrary1.dll 和 ClassLibrary2.dll 的单个 nuget 包,并且生成的 .nuspec 列出了依赖项 Newtonsoft.Json。

我尝试做这样的事情:创建了一个虚拟 .csproj 并添加了对 ClassLibrary1 & 2 的引用,并使用 -IncludeReferencedProjects: Ex:- 创建了一个 nuget 包

dotnet new classlib -o dummyNuget
dotnet add reference ClassLibrary1.csproj
dotnet add reference ClassLibrary2.csproj
nuget pack dummyNuget.csproj -IncludeReferencedProjects
Run Code Online (Sandbox Code Playgroud)

它生成以下 .nuspec 文件,缺少 NewtonSoft 依赖项。

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>dummynuget</id>
    <version>1.0.0</version>
    <authors></authors>
    <description>Description</description>
    <dependencies />
  </metadata>
</package>
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?如何使用 -IncludeReferencedProjects 和列出的所有依赖项创建单个 nuget 包。

示例 Github Repo 可快速重现问题:https://github.com/vivekscripts/TestNugetPack/tree/main

我知道常见的方法是首先将源文件合并到一个项目中,然后使用 dotnet pack 发布单个包,但可以说,由于跨团队依赖关系,该选项并不容易使用。

小智 5

您可以使用“dotnet pack”通过一些技巧来实现这一点。

对于此场景,在 PowerShell 中,我运行以下命令来创建 (3) 项目、添加项目引用,并添加对 NewtonSoft.Json 的 Nuget 引用。

# Create projects
dotnet new classlib -o ClassLibrary1
dotnet new classlib -o ClassLibrary2
dotnet new classlib -o dummyNuget

# Add references
dotnet add dummyNuget reference ClassLibrary1
dotnet add dummyNuget reference ClassLibrary2
dotnet add dummyNuget package Newtonsoft.Json
dotnet add dummyNuget package Nuget.Build.Tasks.Pack

# Create nuget package
dotnet build dummyNuget
Run Code Online (Sandbox Code Playgroud)

创建这些项目后,您必须修改 *.csproj ProjectReference 条目以包含“PrivateAssets”。

  <!-- To ensure project refernece DLLs are included, must set PrivateAssets="All" -->
  <ItemGroup>
    <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" PrivateAssets="All" />
    <ProjectReference Include="..\ClassLibrary2\ClassLibrary2.csproj" PrivateAssets="All" />
  </ItemGroup>
Run Code Online (Sandbox Code Playgroud)

接下来是黑客攻击。可以将此部分添加到项目中,以确保 ProjectReferences 中的 DLL 包含在 nuget 包的 lib/net6.0 文件夹中。

<!-- Fix for dotnet pack not including private (project) references -->
  <PropertyGroup>
    <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
  </PropertyGroup>

  <Target Name="CopyProjectReferencesToPackage" DependsOnTargets="BuildOnlySettings;ResolveReferences">
    <ItemGroup>
      <!-- Filter out unnecessary files -->
      <_ReferenceCopyLocalPaths Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference')->WithMetadataValue('PrivateAssets', 'All'))"/>
    </ItemGroup>

    <!-- Print batches for debug purposes -->
    <Message Text="Batch for .nupkg: ReferenceCopyLocalPaths = @(_ReferenceCopyLocalPaths), ReferenceCopyLocalPaths.DestinationSubDirectory = %(_ReferenceCopyLocalPaths.DestinationSubDirectory) Filename = %(_ReferenceCopyLocalPaths.Filename) Extension = %(_ReferenceCopyLocalPaths.Extension)" Importance="High" Condition="'@(_ReferenceCopyLocalPaths)' != ''" />

    <ItemGroup>
      <!-- Add file to package with consideration of sub folder. If empty, the root folder is chosen. -->
      <BuildOutputInPackage Include="@(_ReferenceCopyLocalPaths)" TargetPath="%(_ReferenceCopyLocalPaths.DestinationSubDirectory)"/>
    </ItemGroup>
  </Target>
  <!-- End of dotnet pack fix -->
Run Code Online (Sandbox Code Playgroud)

完成这些更改后,我们可以运行 dotnet pack 来获取引用了正确依赖项并在 lib 文件夹中包含本地依赖项的 nuget 包:

dotnet pack dummyNuget\dummyNuget.csproj
Run Code Online (Sandbox Code Playgroud)

我使用这两个链接作为指南,顺便说一句:

https://josef.codes/dotnet-pack-include-referenced-projects/

https://dev.to/yerac/include-both-nuget-package-references-and-project-reference-dll-using-dotnet-pack-2d8p