如何将引用的项目打包到nuget包中?

问题描述 投票:0回答:2

我有一个 C# 解决方案,其中包含 3 个项目;应用程序服务器、应用程序客户端和应用程序公共端。服务器和客户端都有一个对 common 的项目引用。

我想打包服务器和客户端,以便我组织中的其他团队可以使用它们。我设置了一些自动构建管道来执行此操作,并且他们为服务器和客户端发布 nuget 包。他们不打包或发布通用的。当我检查 nuget 包时,我可以看到它们引用了 common 包。

有没有办法让他们自己构建该项目?理想情况下,我不想发布通用包,因为它非常特定于我的应用程序,并且它是其他部门独立使用的东西并没有真正意义。如果我能帮忙的话,我也不想担心额外的 nuget 包(事实上,Common 实际上是几个项目)。

.net-core nuget nuget-package
2个回答
14
投票

如果您的项目是“旧式”/非 SDK/传统 csproj,并且如果任何项目使用 NuGet 包,如果所有这些 NuGet 引用都是使用

packages.config
定义的,那么您可以使用
nuget.exe pack -IncludeReferencedProjects
。但是,如果您的任何项目使用
PackageReference
定义其包引用(新的 SDK 样式项目只能使用 PackageReference),则
nuget.exe pack
将无法为这些包正确创建 NuGet 依赖项。对于 SDK 风格的多目标项目,
nuget pack
可能会完全失败。

打包使用

PackageReference
的项目或任何 SDK 样式项目的唯一受支持的方法是使用 NuGet 的 MSBuild 包目标(
dotnet pack
msbuild -t:pack
)。但是,这没有与 nuget.exe 的
IncludeReferencedProjects
等效的功能。

如果您的项目是 SDK 风格,那么创建和发布一个或多个包确实应该不会更困难。只需在您的解决方案上运行

dotnet pack
,每个可打包项目都会被打包(请记住将您不想成为包的任何类库项目标记为不可打包)。然后使用您最喜欢的脚本语言查找并发布所有 nupkg 文件。例如(
Get-ChildItem -Recurse -Filter *.nupkg $SLN_DIR | ForEach-Object { & dotnet nuget push $_ }
,或将所有 nupkg 复制/移动到一个位置(或使用适当的设置让 NuGet 首先在那里创建包)并使用
dotnet nuget push *.nupkg

NuGet 团队建议每个程序集使用一个包,并且该工具会自动为项目引用创建 NuGet 依赖项,因此一切都“开箱即用”。要创建包含所有程序集而不是 NuGet 依赖项的包,需要您做大量工作。


0
投票

将以下内容放入

./Directory.Build.targets

<Project>
  <PropertyGroup>
    <TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);IncludeP2POutput</TargetsForTfmSpecificBuildOutput>
  </PropertyGroup>

  <Target Name="IncludeP2POutput" DependsOnTargets="ResolveReferences">
    <ItemGroup>
      <BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference')->WithMetadataValue('PrivateAssets', 'all'))" />
    </ItemGroup>
  </Target>
</Project>

然后将

PrivateAssets="all"
添加到您想要打包到父母包裹中的所有
ProjectReference

以下是建议的逐步运作方式:

  1. 创建或更新

    ./Directory.Build.targets
    文件: 在项目或解决方案的根目录中,创建或更新
    Directory.Build.targets
    文件。该文件允许您自定义解决方案中所有项目的构建过程。

  2. 定义自定义构建目标: 在

    ./Directory.Build.targets
    文件中,定义一个名为
    IncludeP2POutput
    的自定义构建目标。该目标将在构建过程中执行,并将确定要包含在父项目的 NuGet 包中的项目引用。

  3. 修改

    TargetsForTfmSpecificBuildOutput
    属性: .NET 构建系统使用
    TargetsForTfmSpecificBuildOutput
    属性来确定在特定目标框架的构建过程中应执行哪些目标。通过向此属性添加
    IncludeP2POutput
    ,您可以告诉构建系统为父项目的每个目标框架运行自定义构建目标。

  4. PrivateAssets="all"
    添加到相关
    ProjectReference
    元素: 在父项目(引用其他项目的项目)中,找到要包含在 NuGet 包中的
    ProjectReference
    元素。将属性
    PrivateAssets="all"
    添加到这些
    ProjectReference
    元素。此属性告诉构建系统将这些引用视为私有资产,这意味着它们不会被使用项目视为依赖项。

  5. 自定义构建目标逻辑: 自定义构建目标

    IncludeP2POutput
    在构建过程中触发,并在
    ResolveReferences
    目标(内置目标)之后运行。在目标内部,定义
    ItemGroup
    来选择具有指定元数据值的项目引用(
    ReferenceSourceTarget
    设置为
    'ProjectReference'
    PrivateAssets
    设置为
    'all'
    )。然后,这些引用将添加到
    BuildOutputInPackage
    项目组中。

按照以下步骤操作,当您在父项目上运行

dotnet pack
时,带有
PrivateAssets="all"
的所选项目引用将包含在父项目的 NuGet 包中。将父项目作为包使用的其他项目不会将这些引用视为依赖项,从而使它们有效地隐藏。

请注意,.NET SDK 和构建系统的行为和功能可能会随着时间的推移而发展,因此有必要参考 Microsoft 官方文档和发行说明,以获取有关此主题的最新信息。

© www.soinside.com 2019 - 2024. All rights reserved.