如何将多层依赖的C#项目A打包为包含所有NuGet依赖的包?
问题背景
我的C#项目层级结构如下:
Project-A package1 package2 Project-B package3 package4 Project-C package5 package6
引用关系:
- Project-A 引用 package1、package2 和 Project-B
- Project-B 引用 package3、package4 和 Project-C
- Project-C 引用 package5、package6
我需要把Project-A打包成NuGet包,让这个包直接依赖package1到package6,而不是依赖Project-B、Project-C这些内部项目。但遇到了两个问题:
- 用自定义.nuspec打包时,安装包会尝试下载Project-B、Project-C作为NuGet包,导致还原失败
- 直接用
dotnet pack命令,无法自动把所有package1-6都注册为依赖
我当前的.nuspec文件内容:
<?xml version="1.0" encoding="utf-8"?> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>ProjectA.Nuget</id> <version>1.0.0</version> <title>ProjectA.Nuget</title> <authors>Me</authors> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>Description.</description> <dependencies> <dependency id="package1" version="[6.0.11]" /> <dependency id="package2" version="[6.0.11]" /> <dependency id="package3" version="[6.0.11]" /> <dependency id="package4" version="[6.0.11]" /> <dependency id="package5" version="[6.0.11]" /> <dependency id="package6" version="[6.0.11]" /> </dependencies> </metadata> </package>
解决办法
方法1:调整项目引用的打包行为
针对内部项目引用(ProjectA→ProjectB,ProjectB→ProjectC),修改它们的.csproj文件,让打包时不把这些内部项目作为依赖,而是传递它们的Package依赖。
- 打开Project-A的.csproj文件,找到Project-B的引用节点,添加属性:
<ProjectReference Include="..\Project-B\Project-B.csproj"> <PrivateAssets>All</PrivateAssets> <IncludeAssets>compile;runtime</IncludeAssets> </ProjectReference>
PrivateAssets="All"表示这些项目引用的内容不会被打包到NuGet的依赖中,IncludeAssets则保留编译和运行时的引用。
- 同样,打开Project-B的.csproj文件,对Project-C的引用做相同修改:
<ProjectReference Include="..\Project-C\Project-C.csproj"> <PrivateAssets>All</PrivateAssets> <IncludeAssets>compile;runtime</IncludeAssets> </ProjectReference>
修改完成后,直接运行dotnet pack Project-A.csproj -c Release,生成的NuGet包就会自动包含package1-6作为依赖,不会再出现Project-B、Project-C的依赖项。
方法2:修改.nuspec并配合打包参数
如果坚持用自定义.nuspec文件,需要打包时排除内部项目依赖,确保只有手动定义的package1-6生效。
保持你的.nuspec文件不变,打包时执行以下命令:
dotnet pack Project-A.csproj -c Release /p:NuspecFile=你的nuspec文件路径 /p:IncludeReferencedProjects=false
/p:IncludeReferencedProjects=false参数会阻止打包工具自动添加Project-B、Project-C作为依赖,这样.nuspec里手动写的package依赖就会成为唯一的依赖项。
可选优化:统一管理Package版本
如果所有package版本都是6.0.11,可以在解决方案根目录创建Directory.Packages.props文件,统一管理版本,避免重复写版本号:
<Project> <PropertyGroup> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> </PropertyGroup> <ItemGroup> <PackageVersion Include="package1" Version="6.0.11" /> <PackageVersion Include="package2" Version="6.0.11" /> <PackageVersion Include="package3" Version="6.0.11" /> <PackageVersion Include="package4" Version="6.0.11" /> <PackageVersion Include="package5" Version="6.0.11" /> <PackageVersion Include="package6" Version="6.0.11" /> </ItemGroup> </Project>
之后项目文件和nuspec中的版本号可以简化,后续升级版本只需修改这一个文件即可。
内容的提问来源于stack exchange,提问作者SourCreamKun

