Add dependencies of reference projects to NuGet package

Viewed 3167

I'm using dotnet pack command for creating a NuGet package for the following scenario:

The projects structure:

Project B
|----> Project A

Project A
|----> SomePackage

I want to create a single NuGet package the contains ProjectB.dll, ProjectA.dll, and SomePackage as NuGet package dependency.

In order to include ProjectA.dll as part of the NuGet package (and not package dependency), I used the following solution that suggests here.

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

The issue:

When I run dotnet pack ProjectB.csproj I'm getting a single package the contains ProjectA.dll and Project B.dll, but without a dependency to SomePackage.

The question: How do I add the dependency to SomePackage to ProjectB NuGet package?

Possible solutions:

  1. Manually add a package reference from ProjectB to SomePackage.
  2. Create ProjectB.nuspec file and manually add the dependency to SomePakcage.

The disadvantage of the 2 approaches: I will need to add the dependency for every NuGet package that ProjectA use, which is very easy to forget and breakable.

1 Answers

You have used PrivateAssets="all" for Project A which means that its transitive dependencies are private and cannot be access by the main Project B. We usually use it to disable the dependencies of referenced projects.

So if you use that, you cannot get the transitive dependencies from the referenced projects. And it will make Project A as a assembly dll and will make it lose the ability of nuget package and its transitive dependencies.

If you still want to achieve the goal, you should note these:

1) directly copy the transitive dependencies like PackageReference node from Project A's csproj into Project B's csproj.

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

   ......

In this case, you do not have to use ProjectB.nuspec or nuget package manager UI.

2) Give up using PrivateAssets="all" for Project A and make Project A as a nuget package. Ensure the integrity of its nuget features.

Apart from this, there is no other way.

Related