SoFunction
Updated on 2025-04-14

C# How to convert project references into package dependencies when packaging multiple projects (latest recommendation)

Project background

A group of class libraries has been developed recently, and there will be about five or six projects. A Core, plus several implementation libraries for different products, A/B/C/D... they all rely on Core.

First of all, I want to unify the version number, this is easy to set by.

Secondly, each library must be packaged separately.

The problem is that in the development stage, sub-projects refer to Core through project, which is easy to debug. How to automatically add dependencies on Core packages when packaging?

After experiments, three methods can be summarized:

1. Convert ProjectReference to NuGet dependencies during generation (Not Work)

This DeepSeek recommended solution, but unfortunately, I did not succeed in experimenting.

Its project structure is as follows:

<ItemGroup>
  <ProjectReference Include="..\Core\" >
    <PrivateAssets>all</PrivateAssets>
    <Publish>true</Publish>
    <Version>$(PackageVersion)</Version>
    <PackageId></PackageId>
  </ProjectReference>
</ItemGroup>
<Target Name="ForcePackageReferenceConversion" BeforeTargets="GenerateNuspec">
  <ItemGroup>
    <_PackageReferencesToAdd Include="@(ProjectReference->WithMetadataValue('Publish', 'true'))">
      <PackageId>%(PackageId)</PackageId>
      <Version>%(Version)</Version>
    </_PackageReferencesToAdd>
    <PackageReference Include="@(_PackageReferencesToAdd->'%(PackageId)')" Version="%(Version)" />
  </ItemGroup>
</Target>

Its core idea is to cast the project reference in the package reference before generating .nuspec.

I also asked Github Copilot, and it also said ok, but... please give me some advice from experienced gardeners.

2. Quote according to conditions

Project structure:

&lt;ItemGroup&gt;
  &lt;!-- Used during development ProjectReference --&gt;
  &lt;ProjectReference Include="..\Core\"
                    Condition="'$(IsPackaging)' != 'true'" /&gt;
  &lt;!-- Used when packaging PackageReference --&gt;
  &lt;PackageReference Include=""
                    Version="$(PackageVersion)"
                    Condition="'$(IsPackaging)' == 'true'" /&gt;
&lt;/ItemGroup&gt;

Then use the command to generate:

dotnet pack -p:IsPackaging=true

This method is feasible.

3. Specify the .nuspec file

Finally, I thought of using traditional .nuspec files. (I like the previous package management method, /nuspec, and I don't understand why MS has to stuff everything into the project file.)

Project structure:

  &lt;!-- Specify customization nuspec File path --&gt;
    &lt;NuspecFile&gt;&lt;/NuspecFile&gt;
    &lt;!-- transfer MSBuild Attribute to nuspec Variables in --&gt;
    &lt;NuspecProperties&gt;$(NuspecProperties);
      id=$(PackageId);
      version=$(Version);
      company=$(Company);
      authors=$(Authors);
      product=$(Product);
      copyright=$(Copyright);
      license=$(PackageLicenseExpression);
      projectUrl=$(PackageProjectUrl);
      repositoryUrl=$(RepositoryUrl);
      repositoryType=$(RepositoryType);
      icon=$(PackageIcon);
      config=$(Configuration)
    &lt;/NuspecProperties&gt;

It assigns the properties defined in it to nuspec one by one.

Verification is feasible.

This is the article about how to convert project references to package dependencies when packaging C# multi-projects. For more related content on packaging C# multi-projects, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!