Introducing NuGetSolver: A Powerful Tool for Resolving NuGet Dependency Conflicts in Visual Studio

Erick Yondon

Managing dependencies on complex projects can be overwhelming. Developers often grapple with numerous direct and transitive dependencies across multiple projects. When different projects share dependencies with varying versions, manual conflict resolution becomes necessary, which can be tedious and error-prone, as fixing one issue may inadvertently create others.

Today, we are excited to introduce a new experimental Visual Studio extension called NuGetSolver which was developed in collaboration with Microsoft Research, which aims to simplify the process by automatically resolving NuGet dependency conflicts in your projects. It efficiently tackles the following most common NuGet errors and warnings:

  • NU1107 – Unable to resolve dependency constraints between packages.
  • NU1202 – A dependency package doesn’t contain any assets compatible with the project.
  • NU1605 – A dependency package specified a version constraint on a higher version of a package than restore ultimately resolved.
  • NU1701 – PackageTargetFallback / AssetTargetFallback was used to select assets from a package.

Onboarding to NuGet.Solver extension

To get started with NuGetSolver, you can download the extension from VS Marketplace: NuGetSolver NuGetSolver is a powerful Visual Studio extension designed to help you tackle NuGet dependency conflicts with ease. It takes into consideration all dependencies and provides intelligent and automated suggestions to resolve dependency conflicts in your projects.

You may have encountered errors like NU1605 and NU1701:

Image NuGetSolver NU1605 Errors

You can run the tool from the “Solution Explorer” by right-clicking and selecting “Resolve Dependency Conflicts”.

Image NuGetSolver Start

After a brief calculation to determine if it can generate suggestions, the tool displays the differences between the current and suggested states. Toggle “Show only changes” to view the entire dependency list. By default, it suggests stable versions, unless the original version is a preview, as seen with Microsoft.NET.Test.Sdk in this example. If desired, toggle “Include prerelease” to see suggestions with prerelease versions for all packages.

If the recommended suggestion looks satisfactory, click “Apply fix” and try rebuilding the solution to check if the dependency conflicts are resolved.

Note: It is recommended to enable source control in your repository, so you can easily revert any changes made by NuGetSolver if necessary.

Image NuGetSolver Dialog

You can run the tool even if your solution doesn’t have any dependency conflicts at the moment. It will upgrade your dependencies while keeping the changes minimal. Upgrading packages one by one using NuGet Package Manager can be slow and may sometimes fail due to other dependency constraints, making NuGetSolver a more efficient alternative.

Requirements:

  • Visual Studio 2022 is required.
  • This tool requires an internet connection to function properly, as it needs to retrieve available versions of packages in the solution from nuget.org and download the cache database file from our cache hosting service.

Usage Recommendations and Known Constraints:

  • Only the nuget.org feed (https://api.nuget.org/v3/index.json) is currently supported. Please ensure that your sources in the nuget.config file for your solution resemble the following: Image NugetConfigDefault
  • Multi-feed and local package feeds are not supported.
  • Multi-targeting is not fully supported yet; the tool may generate a fix, but it might not work for all target frameworks.
  • Apply Fix doesn’t fully support updating versions if custom MSBuild logic is used for setting the version. You may need to manually update the versions.
  • Central Package Management (CPM) is not fully supported; the tool can generate fixes, but you may need to manually update the versions in the Directory.Packages.props file.
  • The tool may not consider all available preview versions when Include pre-release is toggled during suggestion calculations.
  • For packages.config or legacy-sdk style style projects, it can generate suggestions, but cannot apply the fix directly. You may need to apply the fix manually.
  • NuGetSolver may resolve compile-time dependency conflicts, but runtime errors could still occur.
  • Currently, NuGetSolver does not verify if suggested versions have known vulnerabilities. As a result, it might recommend a version with known vulnerabilities. You can use the auditing functionality in NuGet to help you resolve these.
  • Does not add a new direct dependency or promote any transitive dependencies to direct dependencies to resolve conflicts.

Conclusion

NuGetSolver is a valuable tool for developers looking to simplify NuGet dependency management in Visual Studio. By automating the conflict resolution process and providing a visual representation of your dependency graph, NuGetSolver saves time and allows you to focus on building amazing applications. Give NuGetSolver a try today and experience the difference it can make in your development workflow.

Feedback

Your feedback is important to us. Please rate the extension and provide comments on the VS Marketplace to help us improve it.

If there are any problems with this extension, check Visual Studio Developer Community for existing issues. For new issues, let us know via the Report a Problem option found in your favorite IDE under Help > Report a Problem.

8 comments

Leave a comment

  • Rand Random 1

    and this isn’t part of the nuget manager, why?

    • Erick YondonMicrosoft employee 2

      We are experimenting with this functionality and decided to ship it as an extension to validate it.

  • Hans Erik Lange 0

    Why would you roll your own instead of help integrating an existing open source product like paket?

    • Davyd McColl 2

      Paket users are a minority – sorry, but it’s true. I stopped using Paket when I realised that it’s a very non-standard modification to the build process. Yes, Paket does some things way better (iirc, dependencies are installed as dependencies, not simply added to the existing PackageReference’s), but it’s not the standard way to access nuget packages.

      A better request might be “can we have this added to nuget.exe and the ‘dotnet nuget’ command set?” – which I’ve raised (:

  • Davyd McColl 3

    Once the dust has settled (because I understand this is a little experimental now), this is the kind of functionality that should be built into nuget.exe and the dotnet nuget commands.

    It would be nice if the tool can also solve this very common problem (at least for me and people who use my packages):

    Packages which are released in lock-step (eg PeanutButter.*, NExpect/NExpect.*) always trip up nuget processes. What I mean by “lock-step” is that when I release version x.y.z of one, the entire suite is released at that version, so there’s no confusion about which packages work together – same number = works. This is find for an initial install – eg if I install NExpect.Matchers.NSubstitute, the correct version of NExpect is imported. However, no tooling that I’ve used lately manages to get this right – everything will fail with the “can’t install {package} at x.y.z because a dependency is already at x.y.(z-1) and the new version requires x.y.z”. The older nuget upgrade would attempt to upgrade packages – but can’t apply to new sdk-style projects. dotnet nuget doesn’t even _have_ an upgrade command, so there seems to be a reliance on either the IDE sorting it out after user interaction, or the user manually upgrading things.

    No, the solution is not to stop releasing in lock-step – there are times when new functionality is added and an old assembly won’t have it, so packages should be upgraded.

  • Michael Taylor 4

    Sounds like a good first step but honestly does anyone rely solely on Nuget.org for their packages outside open source and MS? In my experience everyone has private packages (in a private feed) + public packages (in Nuget). It would be critical to support multiple feeds before this can really be tested in a more realistic environment.

    Hopefully it can start solving some common problems like newer packages only working with newer frameworks whereas we are supporting older frameworks as well. It causes havoc when I have to use v6 versions of packages for the net6 build and v8 versions of packages for the net8 build (of the same project) or live with updates that I cannot apply. Transient dependencies make this even worse.

  • Mariusz 0

    Why it’s a Visual Studio extension and not just part of nuget.exe / dotnet nuget command / .NET SDK? Even if it’s and experiment, it makes no sense to force it to be VS extension.
    Another attempt to move essential .NET’s devtools to VS? I think Microsoft should’ve learned something from the dotnet watch controversy.

Feedback usabilla icon