.NET Core NuGet 多项目套餐打包的正确姿势

NuGet 默认只支持一个菜一个菜打包,不支持套餐打包。当对一个 csproj 项目进行 nuget 打包时(比如使用 dotnet pack 命令),只会将当前项目 build 出来的 dll 程序集文件打包进 nupkg 文件,而所引用项目的 dll 文件不会被打包进去。要解决这个问题需要在 csproj 文件中添加专门的 msbuild 配置,这篇随笔分享一下刚学到的新姿势。

之前我们是通过 _PackageFiles 配置实现的,但要一个一个手写要打包进去的程序集文件名称,既麻烦又容易出错,有点追求的程序员都不喜欢这样的解决方法。

<ItemGroup> 
  <_PackageFiles Include="$(OutputPath)\Cnblogs.UCenter.DTO.dll">
    <BuildAction>None</BuildAction>
    <PackagePath>lib\$(TargetFramework)\</PackagePath>
  </_PackageFiles>
  <_PackageFiles Include="$(OutputPath)\Cnblogs.UCenter.ValueObjects.dll">
    <BuildAction>None</BuildAction>
    <PackagePath>lib\$(TargetFramework)\</PackagePath>
  </_PackageFiles>
</ItemGroup>

昨天在 stackoverflow 上找到了更简单优雅的基于 BuildOutputInPackage 配置的解决方法

<PropertyGroup>
  <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>
<Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences">
  <ItemGroup>
    <BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
  </ItemGroup>
</Target>

除此之外,还需要对所引用的项目添加 <PrivateAssets>all</PrivateAssets> 设置。

<ItemGroup>
  <ProjectReference Include="..\Cnblogs.UCenter.DTO\Cnblogs.UCenter.DTO.csproj">
    <PrivateAssets>all</PrivateAssets>
  </ProjectReference>
  <ProjectReference Include="..\Cnblogs.UCenter.ValueObjects\Cnblogs.UCenter.ValueObjects.csproj">
    <PrivateAssets>all</PrivateAssets>
  </ProjectReference>
</ItemGroup>

不然安装这个包时 nuget 就会通过 nuget 源找所引用项目的 nuget 包。

NU1102: Unable to find package Cnblogs.UCenter.DTO with version (>= 2.4.2)

加了 PrivateAssets 设置,就会在当前 NuGet 包的 lib 文件夹找对应的程序集文件。

2022年10月29日更新:

今天通过博文 How to include DLL from project reference in NuGet package 发现了一个更简单的解决方法

  • 安装 nuget 包 Teronis.MSBuild.Packaging.ProjectBuildInPackage
  • 对所引用的项目添加 <PrivateAssets>all</PrivateAssets>
posted @ 2019-09-29 12:13  dudu  阅读(2866)  评论(5编辑  收藏  举报