Single package version per solution

Issue 913

Problem Statement

When using an assembly, it’s rare for developers to want different versions of the same assembly within a single solution. Most of the time, if you’re using an assembly in one project of the solution, and need to use the same assembly in another project in the same solution, you want the exact same version. And if you update the assembly in one project, you’re going to want to update the assembly in the other.

This conclusion is based on the results of a recent poll we conducted.

However, you can easily get into this state with NuGet where different projects in the same solution have different versions of a common package.

Feature  Proposal

The proposal is to change NuGet to guarantee that all projects in a solution use the same version of any given package

Let’s look at multiple ways this can happen and the proposed new behavior to handle this.

For all these examples, we’ll use the following Solution as our example. It contains two projects, MvcApplication1 and ClassLibrary1.

MvcApplication1 - Microsoft Visual Studio (Administrator)

Installing Packages

  • Install Log4Net 1.0 into MvcApplication1
  • Install Log4Net 1.1 into ClassLibrary1

Simply installing packages can get you into a bad state. Suppose you install Log4Net 1.0 into MvcApplication1. Then a few days later Log4Net 1.1 comes out and you install it into ClassLibrary1. Now you have two projects with different versions of the same assembly.

Fix: In this situation, NuGet will upgrade Log4Net in all projects (MvcApplication1) to the same version being installed.

Updating Packages

  • Install Log4Net 1.0 into MvcApplication1
  • Install Log4Net 1.0 into ClassLibrary1
  • Update Log4Net to version 1.1 in ClassLibrary1

This is really just a variant of the previous case. After installing the same library to both projects, we go and update one of the packages to the latest version.

Fix: In this situation, NuGet will upgrade Log4Net in all projects (MvcApplication1) to the same version.

Installing/Upgrading Dependencies

In this case, MyLogger 1.0 is a package that depends on Log4Net 1.1.

  • Install Log4Net 1.0 into MvcApplication1
  • Install MyLogger 1.0 into ClassLibrary1

Notes: Again, this is really a variant of the first case, but is worth calling out because it’s more subtle. In this case, installing MyLogger 1.0 will bring in a newer version of Log4Net into the project. In this case NuGet will need to upgrade Log4Net to this version in all projects.

Interesting cases

Installing a lower version

  • Install Log4Net 1.1 into MvcApplication1
  • Install Log4Net 1.0 into ClassLibrary1

in this case, the developer is attempting to install an older version of a library into a class library for whatever reason. This couldn’t happen via the dialog, but could happen in the console. The later examples will show why this might happen.

Open Question:

  • What should NuGet do in this situation?
    • Downgrade Log4Net in all other projects to the target version?
    • Install the later version of NuGet?
    • Throw an error stating a newer NuGet is already installed in the solution.

Answer: Throw an error.

Installing a lower version due to dependencies

In this case, MyLogger 1.0 is a package that depends on Log4Net >= 1.0.

  • Install Log4Net 1.1 into MvcApplication1
  • Install MyLogger 1.0 into ClassLibrary1

In his case, since the existing Log4Net version in the solution is compatible with the version range of the package we’re installing, NuGet will instead install Log4Net 1.1 into ClassLibrary1 rather than Log4Net.

Conflicts

One result of this feature is there are more chances for version conflicts because installing/upgrading packages will check all projects in a solution for a conflict. Note that all other conflict cases are pretty much similar to the ones we already have today. The only change is looking at every project for conflicts.

Installing a conflicting package

In this case, MyLogger 1.0 is a package that depends on Log4Net == 1.0 (exactly 1.0).

  • Install MyLogger 1.0 into MvcApplication1 (and thus Log4Net 1.0)
  • Attempt to install Log4Net 1.1 into ClassLibrary1

In this scenario, attempting to install Log4Net 1.1 into the second project will attempt to upgrade Log4Net to 1.1 in the first project. Unfortunately, this will cause a conflict with the MyLogger dependency on Log4Net.

NuGet will fail the installation and report a conflict with the package in the first project. Note this is the same behavior as before, but now NuGet looks at all projects for conflict.

Last edited Apr 29, 2011 at 6:24 PM by haacked, version 9