将引用项目的依赖项添加到 NuGet 包中。

8

我正在使用dotnet pack命令创建一个NuGet包,用于以下场景:

项目结构:

Project B
|----> Project A

Project A
|----> SomePackage

我想创建一个单一的NuGet包,其中包含ProjectB.dllProjectA.dllSomePackage作为NuGet包依赖项。

为了将ProjectA.dll包含在NuGet包中(而不是作为包依赖项),我使用了以下解决方案,建议参考这里

ProjectB.csproj 中:

  <ProjectReference Include="ProjectA.csproj" PrivateAssets="all"/>

  <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>

问题:

当我运行dotnet pack ProjectB.csproj时,我只得到了一个包含ProjectA.dllProjectB.dll的单个软件包,但没有依赖于SomePackage

问题是:如何将依赖项添加到ProjectB NuGet软件包中的SomePackage

可能的解决方案:

  1. 手动从ProjectB添加对SomePackage的软件包引用。
  2. 创建ProjectB.nuspec文件,并手动添加对SomePakcage的依赖项。

这两种方法的缺点是:我需要为ProjectA使用的每个NuGet软件包都添加依赖项,这很容易被遗忘并且容易出错。

1个回答

0

您在A项目中使用了PrivateAssets="all",这意味着其传递依赖项是私有的,主要的B项目无法访问。我们通常使用它来禁用引用项目的依赖项。

因此,如果您使用它,就无法从引用的项目获取传递依赖项。这将使A项目成为一个程序集dll,并使其失去NuGet包和其传递依赖项的能力。

如果您仍然想实现目标,应注意以下几点:

1)直接将A项目的csproj中的传递依赖项(如PackageReference节点)复制到B项目的csproj中。

 <PackageReference Include="SomePackage" Version="*.*.*" />

   ......

在这种情况下,您不必使用ProjectB.nuspec或nuget包管理器UI。

2) 放弃对项目A使用PrivateAssets="all",并将项目A作为nuget包。确保其nuget功能的完整性。

除此之外,没有其他方法。


谢谢你的回答。我想使用 PrivateAssets="all",因为我只需要创建一个包含所有项目引用和所有包依赖项的单个NuGet包。 选项1与我提到的相同,但在我的情况下,它的缺点更大,我有更多的项目引用,其中包括来自所有项目引用的约20个包引用,这意味着需要大量手动工作+很容易忘记依赖项并创建错误的NuGet包(只能在运行时检测到)。 - itaiy
您说的方案2也是一个好的解决方案,但我不想将所有项目引用暴露给用户作为NuGet包,我只需要一个单独的NuGet包。 - itaiy
当然。要解决这个问题,您必须直接复制引用的“项目A”的PackageReference节点到“项目B”中。毕竟,“项目A”作为中间桥梁已经失去了Nuget功能,因此您必须将其依赖节点添加到“项目B”中。为了做到这一点,您必须这样做。 - Mr Qian
正如我之前提到的,唯一的问题是,如果将来有人向项目A添加另一个依赖项,而没有将其添加到项目B中,我们将得到一个故障的NuGet包,只有在运行时才会出现MethodNotFound或类似异常。这个解决方案非常容易出问题。 - itaiy
感谢分享信息。嗯,我不确定是否有实现该功能的函数。也许没有。在后续操作中,您可以使用“管理解决方案的Nuget包”。右键单击解决方案->“管理解决方案的Nuget包”。这将使Nuget包在两个项目上都安装。 - Mr Qian
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接