2

I have a .NET app called Application.

This application depends on two NuGet packages:

  • Database, version 2.*
  • Logging, version 3.*

The Database package depends on two additional packages:

  • DTO, version 1.*
  • DAL, version 4.*

Currently, Application uses these concrete package versions: Database version 2.1, Logging version 3.1.

I build my Application, NuGet resolves and downloads the dependencies, so I get DTO version 1.5 and DAL version 4.0. I put my Application into an installation package and deliver to my customer. I tag this release in git with app-1.0.

So my customer gets the following binaries:

  • Application.exe, version 1.0
  • Database.dll, version 2.1
  • Logging.dll, version 3.1
  • DTO.dll, version 1.5
  • DAL.dll, version 4.0

One year later, the customer files a bug which I need to thoroughly analyse. To reproduce the issue, I need the same binaries as the customer, so I check out the tag app-1.0 and want to build my application.

Meanwhile, the DAL and the DTO packages were updated on the NuGet feed: latest DTO version is 1.7 and DAL version is 4.5.

My questions are:

  • When I build my application now, does NuGet resolve the Database dependencies to the latest available versions? So do I get DTO 1.7 and DAL 4.5 instead of DTO 1.5 and DAL 4.0 (which were used to build app-1.0)?
  • If yes, how can I ensure the binary reproducibility of my release using NuGet?
  • If no, how does NuGet manage to resolve the "right" references?
dymanoid
  • 14,771
  • 4
  • 36
  • 64
  • You are using a concrete nuget package with version specified in `packages.config` or in `PackageReference`. You can build your code tagged as `app-1.0` with old versions of packages (if you didn't update them, of course) – Pavel Anikhouski Dec 19 '19 at 12:51
  • @PavelAnikhouski the question is not about the packages I **directly** reference. The question is about the floating **dependencies** of the packages I reference. – dymanoid Dec 19 '19 at 12:52
  • You are specified the minimal versions of dependent packages on nuget. The answer depends on `Database` package configuration. If it works with old versions of `DTO` and `DAL`, it won't be any issues with building the code. There is also no issues if build the code against `app-1.0` without updating a packages versions using `Update-Package` in nuget – Pavel Anikhouski Dec 19 '19 at 12:55

1 Answers1

3

NuGet introduced lock files in version 4.9 (Visual Studio 2017, 15.9), .NET Core SDK 2.1.500. The blog post that introduces it is even titled "Enable repeatable package restores using a lock file"

The blog post only lists one way to enable lock files. One way is to create an empty file named packages.lock.json in the same directory as your project file (csproj), then do a restore. Another way is to run dotnet restore --use-lock-file on the command line. Another way is to set the RestorePackagesWithLockFile MSBuild property to true, which is possible in many ways (property in your project file, property in Directory.Build.props, environment variable, command line argument).

Once the lock file is created, it will always be used, so you no longer need to explicitly opt-in as you need to the first time. Note that restore will update the lock file by default when it finds changes. If you want to fail restore when it can't restore the exact same packages, you need to opt-in to "locked mode", for example dotnet restore --locked-mode, which you probably want to do on your CI machines.

zivkan
  • 12,793
  • 2
  • 34
  • 51