如何将多个项目打包为单个Nuget包并保留全部外部依赖
你使用的nuget pack -IncludeReferencedProjects方案失效的核心原因是:该参数是为老式非SDK风格(.NET Framework时代,用packages.config管理包)的项目设计的,无法识别SDK风格项目(dotnet new classlib默认生成的项目格式)中通过PackageReference声明的Nuget依赖,因此不会将ClassLibrary1引用的Newtonsoft.Json写入最终包的依赖列表。
不需要修改ClassLibrary1、ClassLibrary2的任何代码和项目配置,仅需调整打包入口项目dummyNuget的配置,使用官方dotnet pack命令打包即可,步骤如下:
- 确保本地安装.NET 6及以上版本的SDK(长期支持版本,兼容性最优)。
- 打开dummyNuget目录下的csproj文件,替换为如下配置:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <!-- 目标框架与ClassLibrary1、ClassLibrary2保持一致即可 --> <TargetFramework>net6.0</TargetFramework> <PackageId>自定义你的Nuget包ID</PackageId> <Version>1.0.0</Version> <Authors>自定义作者名</Authors> <Description>自定义包描述</Description> <!-- 注入自定义打包目标,用于收集引用项目的输出dll --> <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput> <!-- 不需要生成XML注释文档的话可以加这行,按需配置 --> <GenerateDocumentationFile>false</GenerateDocumentationFile> </PropertyGroup> <ItemGroup> <!-- 原有两个项目引用保留,新增子节点配置 --> <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj"> <PrivateAssets>all</PrivateAssets> <ExcludeAssets>none</ExcludeAssets> </ProjectReference> <ProjectReference Include="..\ClassLibrary2\ClassLibrary2.csproj"> <PrivateAssets>all</PrivateAssets> <ExcludeAssets>none</ExcludeAssets> </ProjectReference> </ItemGroup> <!-- 自定义打包目标:将引用项目的生成dll复制到Nuget包的输出目录 --> <Target Name="CopyProjectReferencesToPackage" DependsOnTargets="BuildOnlySettings;ResolveReferences"> <ItemGroup> <BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" /> </ItemGroup> </Target> </Project>
配置说明:
PrivateAssets="all"表示不会将ClassLibrary1、ClassLibrary2本身作为Nuget依赖暴露给安装当前包的项目,而是直接把它们的dll打包进当前包内;ExcludeAssets="none"表示两个项目的所有Nuget依赖都会被识别为当前包的依赖,自动写入nuspec文件。
- (可选)删除dummyNuget项目默认生成的空Class1.cs文件,避免生成多余的占位dll。
- 在dummyNuget项目根目录执行打包命令:
dotnet pack -c Release
生成的nupkg包可通过修改后缀为zip解压校验:
- lib目录下同时包含ClassLibrary1.dll、ClassLibrary2.dll
- 解压后查看nuspec文件,dependencies节点下会正确列出Newtonsoft.Json依赖及对应版本号
- 将包安装到测试项目时,会自动引入两个类库的dll,同时自动安装Newtonsoft.Json依赖,不会出现运行时缺程序集的问题。
如果坚持要使用nuget pack命令,需要先将nuget.exe升级到最新版本,同时在ClassLibrary1、ClassLibrary2的csproj中新增<GenerateNuspecDependencies>true</GenerateNuspecDependencies>配置,但该方案对SDK风格项目的兼容性较差,很容易出现依赖遗漏、版本号识别错误的问题,不推荐使用。
内容的提问来源于stack exchange,提问作者VJSharp

