Changing a project reference to a NuGet package reference on build

asp.net packagereference
include nuget package in build
add nuget package to csproj
nuget package vs project reference
.net core nuget package dependencies
packagereference version range
replace project reference with nuget
the project does not support adding package references through the add package command

I have a Visual Studio solution with two projects - a .NET Standard (2.0) library containing some logic and a .NET Framework (4.6.1) class library containing user interface etc. The .NET Framework library then has the .NET Standard library added as a project reference so it can use methods contained in the logic library.

I am then using Azure Pipelines in Azure DevOps to build these two projects, pack them as NuGet packages and push them to a NuGet server provided by Azure Devops (Azure Artifacts).

However, when the NuGet packages are published, they only include dependencies in NuGet on packages that I've added to the projects via NuGet. What I want ideally is when my .NET Standard (logic) library is packaged up and pushed to the NuGet server, a reference to it on NuGet (with the updated version number etc) is added to my .NET Framework (UI) library.

Has anyone else had this issue that can give me some guidance on how to solve it please? I've had a look online and drawn a blank so far.

Thanks!


There are two parts to my answer.

Firstly, if you're using dotnet pack or msbuild -t:pack, without a nuspec file, then project references automatically become nuget dependencies. I verified this using the following commands:

dotnet new classlib -n ProjectA
dotnet new classlib -n ProjectB
dotnet add ProjectB/ProjectB.csproj reference ProjectA/ProjectA.csproj
dotnet pack ProjectB/ProjectB.csproj

ProjectB.1.0.0.nupkg has a nuget dependency on ProjectA v1.0.0. This works "out of the box" with SDK style projects, but if you have an "old style" project (that imports Microsoft.CSharp.targets), you'll need to add a package reference to NuGet.Build.Tasks.Pack. If you use PackageReference, you may need to edit your csproj and set this dependency to set PrivateAssets to all to avoid this package becoming a nuget dependency. I don't know what the equivalent is if you're using packages.config, or if it's even possible. If you're using msbuild or dotnet pack, but you also have your own nuspec file, I recommend against it. Anything you want to do in the nuspec should be possible by setting the right properties or item attributes in your csproj, and let the pack targets generate the nuspec automatically. When you have your own nuspec, parts of nuget's auto-generation gets turned off, so you may be making things harder for yourself.

My memory of nuget pack on old style csproj files is that nuget will automatically make a project reference a nuget dependency as long as the referenced project has a <project name>.nuspec file in the same directory as the <project name>.csproj file (I'm almost certain that it's documented somewhere on docs.microsoft.com/nuget). However, if your dependant project is a SDK style project (like is needed for .NET Core or .NET Standard projects), then I already advised against using a nuspec file with those projects, so you should really consider using the pack targets and stop using nuget pack.

The second part of my answer will directly answer your question, which is about how to make a project reference a package reference on certain builds. Firstly, you need to use pack targets, either by using a SDK style project or by referencing the NuGet.Build.Tasks.Pack package. This way, you don't use a nuspec file, and everything is defined in your csproj, which is just a MSBuild file. MSBuild has conditions, so hand edit your csproj and make your project reference have a certain condition and have the package reference have the opposite condition. I suggest use a variable like $(CI), so you can test the pack using msbuild -t:pack -p:CI=true, and on your CI machine just set CI as an environment variable to true. Since NuGet already has functionality built-in for making project references into nuget dependencies, I recommend using that, and not switching between package and project references, so I'm not going to give a copy-paste example on how to do this. But if this isn't a case of a XY-problem and you really need to do this, then I've already given enough pointers for you to be able to figure out how to do the rest.

Include both Nuget Package References *and* project reference , Recently I have been trying to generate more Nuget packages for our dotnet core projects, utilizing the dotnet pack command. One issue I have  In the NuGet options in Visual Studio (opened using the Tools > NuGet Package Manager > Package Manager Settings menu command), change the Default package management format ” to PackageReference. When you then install a NuGet package into a project for the first time, NuGet uses the PackageReference format.


NuGet CLI has issues with dependencies for PackageReferences and project references (only when the project is a .net Core or .net Standard too?) when not using .nuspec files.

Use dotnet pack or msbuild -t:pack to include the project reference as a nuget dependency. This also resolves issues for PackageReferences not being written as dependencies.

Assuming your .net framework project is out-of-the-box from Visual Studio, you'll need to reference the Nuget.Build.Tasks.Pack nuget package to access the necessary targets. We write this data into the .csproj file with powershell on the build server before any nuget restore so that is isn't forgotten about for new full framework projects (which we are trying to get away from creating). As @zivkan mentioned, you will probably want to

set PrivateAssets to all to avoid this package becoming a nuget dependency

<PackageReference Include="NuGet.Build.Tasks.Pack">
  <PrivateAssets>all</PrivateAssets>
  <Version>4.8.0</Version>
</PackageReference>

Migrate to PackageReference with 3 clicks, By using the Top-level option, you can change any package that's Newly created projects that come with existing NuGet references using  End result CSPROJ. (Click to enlarge) Now if you run dotnet pack you should see any project reference DLL under the lib folder of the package, and if you inspect the nuspec file inside the package (or upload it to your package repo) you should see the nuget dependencies.


Changing a project reference to a NuGet package reference on build

I am afraid you could not convert the project reference to the nuget package reference during building. That because they are two different ways of dealing with references. Although there are now some extensions that can convert a project reference to a nuget package reference, they need manual operation, we could not use it during the building.

Check the another thread for some more details.

So, we could not change the project reference .NET Standard (2.0) library to a NuGet package reference and add to your .NET Framework (UI) library on build.

Personally, to resolve this issue, you could use reference the .net Standard (.netSrd) project as nuget package reference on your local, when you have updated version number nuget package for .net Standard project, you could update this package in your Azure Artifacts, and use custom nuget task command to call nuget update command to update the packages to the latest version when you build your .NET Framework (UI) library.

Check the details info from:

Update NuGet package to last version after build in VSTS

Hope this helps.

Resolve package references to projects · Issue #1151 · dotnet/sdk , NuGet and compilation would resolve the package vs project based on some the docs when want to replace the package with a project reference instead of a Custom build task is not called when building on solution level  Project reference VS NuGet Project reference or NuGet is a very common problem in our development process, we need to choose which one to use based on our actual situation. For example, if the referenced project A is modified frequently during the development process, we recommend to use Project reference.


If you are using the new csproj format (designed for .NET Core but can work with any .NET) then it's pretty simple.

In the projects you want to be released as NuGet packages you have to add in the csproj the following:

<GeneratePackageOnBuild>true</GeneratePackageOnBuild>

Apart from that you only have to reference your other projects with ProjectReferences. MSBuild will build everything, and when publishing the NuGet packages it will change the ProjectReferences to PackageReferences.

NuGet: To Reference, or to NoReference? That is the question., There are two types of NuGet package available on the Sitecore MyGet When adding a Nuget packages from within Visual Studio, you can change the We'll create a new project and select to use Package Reference this  However, I don't need to create new packages all of the time, say I only added a unit test or fixed a bug in the Web Api project, I don't want to create new Nuget packages (or worry about bumping the Package version) if nothing in the Api Client Project (or its dependencies) has changed, but I do still want to regression test it.


If you have a ProjectReference, it will override any package references to the same package ID in the restore graph.

Source: Resolve package references to projects (dotnet github issue)

I tried this myself (added both the ProjectReference and the PackageReference in the csproj file). It successfully builds and the output NuGet file contains the dependency to the other NuGet package.

Renovate your .NET solution · Cezary Piątek Blog, The next change is related to creating your own NuGet packages. All project references are very clearly presented now in the Solution  If possible, resolve to a single reference version. The best solution is to remove the need for different reference versions. Sometimes it’s as easy as going to NuGet manager and changing the versions. This is widely referred as DLL Hell and isn’t in the scope of this article. Some resources to help with DLL Hell are: , ,


Moving from NuGet Package.Config to PackageReference, We discuss the transition from NuGet Package. Net upgrade project, we migrated NuGet packages to PackageReference. has changed the way of including packages without package.config. Package references are directly added in your application just like other files, so no more packages.config. You should package the shared binaries, along with indexed PDB's, into a Nuget package. Nuget was specifically designed to solve these problems. You can index your PDB's by running an indexing tool. TF Build can automatically index your PDB's.


Forcing a Specific Target Platform With PackageReference -- Duane , NET Standard reference when using NuGet with packages.config. file then you will need to convert your project to use PackageReference . Now when you build you will not get any <Reference> nodes auto added for this  To Reference, or to NoReference, that is the question Whether ’tis nobler in the mind to suffer The slings and arrows of outrageous NuGet references Or to take arms against a sea of DLLs. Since 2016, Sitecore has made platform DLLs available as NuGet packages on their MyGet feed.


PackageReference is not supported for non-dotnet core projects , If I move nuget references from packages.config to e.g. Nuget Restore works fine, the project just doesn't build (Type or Namespace could not be found). After changing this to the one bundled with Visual Studio, the issue was fixed. Use NuGet packages (preferred) These instructions assume that you're using PackageReference-style NuGet references. Change your project file (s) to reference MSBuild assemblies from their NuGet packages. Specify ExcludeAssets=runtime to tell NuGet that the assemblies are needed only at build time, and shouldn't be copied to the output directory.