The information is accurate as of this writing, as far as I know.

Contents

What's the Change?

Today, a project's NuGet package information is stored in a project-level packages.config folder. The assemblies are stored in a separate packages folder, usually at the solution level. The project's .csproj file contains Reference elements that point to the assemblies.

Packages.config format folder layout and text samples

Argonautics
|_packages
  |_ParseText.1.0.4.0
    |_lib
      |_net45
        |_ParseText.dll
        |_PersistText.dll
|_Argonautics.sln
|_PlainPlanning
  |_PlainPlanning.cproj
    <Reference Include="ParseText.dll, Version=1.0.4.3, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\packages\ParseText.1.0.4.0\lib\net45\ParseText.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="PersistText.dll, Version=2.3.4.0, Culture=neutral, processorArchitecture=MSIL">
      <HintPath>..\packages\ParseText.1.0.4.0\lib\net45\PersistText.dll</HintPath>
      <Private>True</Private>
    </Reference>
  |_packages.config
    <package id="ParseText" version="1.0.4" targetFramework="net45" />

The PackageReference format moves the package information out of packages.config into the .csproj file, and removes the assembly references. The packages folder is removed, as well, in favor of a user-profile folder found at %userprofile%\.nuget\packages.

PackageReference format folder layout and text samples

Argonautics
|_Argonautics.sln
|_PlainPlanning
  |_PlainPlanning.cproj
    <PackageReference Include="ParseText">
      <Version>1.0.4</Version>
    </PackageReference>
|_%userprofile%\.nuget\packages
  |_ParseText.1.0.4.0
    |_lib
      |_net45
        |_ParseText.dll
        |_PersistText.dll

When the project builds, Visual Studio finds the packages in the expected location and copies the assembly dependencies to the bin folder.

What Are the Advantages?

  • Binaries that can be restored are very hard to accidentally include in source control.
  • Only the package information is shown in References, which is usually what the developer wants to see.
  • Package restore is faster because files aren't copied to a solution folder. Continuous Integration benefits, as well, by having just one well-known package location.
  • Importantly, since the paths to assemblies aren't stored in the .csproj file, version control thrash due to differences between developer environments is eliminated. No more update-package -restore because DLLs can't be found.
  • The PackageReference elemnt allows more flexibity and direct use by MSBuild.
  • For NuGet Package authors, the nuspec information is stored directly in the project file, not in a .nuspect file. Also, Build and Pack tasks are included in MSBuild.

Which Visual Studio Editions and Project Types Does It Work With?

PackageReference is availabe in Visual Studio 2017. As of this writing, per NuGet.org:

Although we’re working to bring the PackageReference goodness to all project types and to make all packages compatible with PackageReference, migration is not presently supported for C++, JavaScript, and ASP.NET (.NET Framework) projects.

Also, some packages capabilities are not fully compatible with PackageReference.

Some examples of scenarios that will not be supported include content folders (we have introduced ContentFiles), XDT transforms, PowerShell scripts i.e. install.ps1 and uninstall.ps1 (only init.ps1 is supported) .

Author Note
Obviously ASP.NET support is important, and projects may depend on packages that aren't compatible. However, its lack doesn't prevent migrating compatible projects.

Is There a Converter?

Yes, there is! It's currently available in the Visual Studio Preview edition. It has some known issues, but seems to work well. See the References for a link to instructions.

Manually Converting to PackageReference.

This works with ASP.NET, too, but is more likely to have problems because of content files (stylesheets, scripts, etc). Need to look into this further.

  1. Backup solution
  2. Open solution
  3. Open a project's packages.config
  4. Open the project's .csproj file
  5. In another text editor, create the PackageReference elements.
    <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
    
    <ItemGroup>
    	<PackageReference Include="[PackageId]" Version="[PackageVersion]" />
    	<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
    </ItemGroup>
    
  6. Right-click References > Manage Nuget Packages
  7. Choose the Installed tab.
  8. Uninstall the packages for the project only.
    There could be more cleanup in .csproj, such as deleting extraneous .target references*
  9. Copy the ItemGroup into the project file and save.
  10. Delete packages.config
  11. Open Package Manager Console, select the project, and run (for example)
    Update-Package -ProjectName Sms.Web.Verifications -Reinstall
  12. Build
  13. Run

I reocmmend doing a file/folder diff from the previous version (easy if using version control). This will reveal problems that a build/run may not catch.

Can I Convert With a Script?

I haven't tried a script, yet, but I don't see why not.

References

Image Attributions

  • By NuGet project team (https://github.com/NuGet/Media) [Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)], via Wikimedia Commons
  • By Microsoft Corporation ([1]) [Public domain], via Wikimedia Commons