Migrating to Package References
One of the better changes in Visual Studio 2017 is the moving of the NuGet packages out of packages.config and into the project file via package references. Unfortunately all the documentation that I’ve seen seems to assume that this is a new project or at least one that was created in Visual Studio 2017. In my experience this is unlikely to be true. This article will discuss the steps I use to migrate an older project to using package references.
The first thing you need to ask yourself is whether you should or not. While having everything in a single file is nice there are some issues with it. The biggest issue is that packages that are referenced this way no longer run config transformations or can modify files that are inserted. If you rely on packages that require this (i.e. EntityFramework) then you’re out of luck.
Secondly support for package references is currently limited. There are mixed documentation on what project types are supported but the general set appears to be this (as of Aug 2017).
- .NET Core
- .NET Standard
- UWP (Creators Update or higher)
- Class Library (.NET Framework)
- Unit Test (.NET Framework)
Updating the Project
The first thing you need to do is ensure you are building using the latest tools. For that you need to edit the project file. You can do so either via text editor or directly in Visual Studio. I recommend using the Project File Tools extension if you do. Find the root
ToolsVersion and change it to
15.0. If you’re using the new project file format then this step is not necessary.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
Cleaning Up Root Properties
Clean up the root
PropertyGroup of any old NuGet properties and add the new properties for the package references.
- Add a
RestoreProjectStyleelement with a value of
- Add an
AutoGenerateBindingRedirectselement with a value of
true. You don’t need to do this in all cases but I’ve never run into issues with having it in.
- Add a
RuntimeIdentifierselement with a value of
- Remove the
RestoreNugetPackageselement if it exists.
The runtime identifier is annoying. You shouldn’t need this but because of some code in the NuGet target that is looking for the old project.json file you can get build errors about a missing project.json without this line. It basically says that you’re targeting Windows. For .NET core projects and projects not targeting Windows you’d use another RID.
<RestoreProjectStyle>PackageReference</RestoreProjectStyle> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <RuntimeIdentifiers>win</RuntimeIdentifiers>
Adding Package References
Now you need to add each of the NuGet packages you depend on to the project file. You can get the initial list from the packages.config file in the project. Create a new
ItemGroup in the project. For each package add a
PackageReference element to the group that identifies the package and version being used.
<ItemGroup> <PackageReference Include="FluentAssertions" Version="4.5.0" /> </ItemGroup>
One benefit of the new reference syntax is that you only need to include packages you have a direct dependency on. If a package has a dependency on another package then you can leave it off and it will get automatically added. Also ensure that you only include the reference once.
Removing Old References
The binary references that are in the file are no longer needed so scan for the list of
Reference elements that point to the packages and remove them. A single package may have multiple references so remove them all.
<ItemGroup> <!-- Remove these <Reference Include="FluentAssertions, Version=18.104.22.168, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL"> <HintPath>..\packages\FluentAssertions.4.5.0\lib\net45\FluentAssertions.dll</HintPath> <Private>True</Private> </Reference> <Reference Include="FluentAssertions.Core, Version=22.214.171.124, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL"> <HintPath>..\packages\FluentAssertions.4.5.0\lib\net45\FluentAssertions.Core.dll</HintPath> <Private>True</Private> </Reference> --> <Reference Include="System" /> <Reference Include="System.Core" /> <Reference Include="System.Xml" /> <Reference Include="System.Xml.Linq" /> </ItemGroup>
Update to MSBuild Restore
You need to ensure you are using the MSBuild restore and not the old NuGet/automatic restore that was previously used. Scan the project file and remove any references to the
RestoreNuGetPackages element. Also remove any references to the Nuget.targets file.
The project file changes are done so save and close it. Reload in Visual Studio. Delete the
packages.config file from the project. You should now test the build.
- Clean the solution.
- Close Visual Studio.
- Delete the packages folder. You do not need the
- Open the solution.
If everything builds correctly then you are good to go.