View NuGet package dependency hierarchy

Like @neil-barnwell solution, but works with NuGet.Core 2.7+

Install-Package NuGet.Core

Here is the code

using System;
using System.Linq;
using System.Runtime.Versioning;
using System.IO;
using NuGet;

public class Program
{
    public static void Main(string[] args)
    {
        var frameworkName = new FrameworkName(".NETFramework, Version=4.0");

        // var packageSource = "https://www.nuget.org/api/v2/";
        var packageSource = Path.Combine(Environment.GetEnvironmentVariable("LocalAppData"), "NuGet", "Cache");

        var repository = PackageRepositoryFactory.Default.CreateRepository(packageSource);
        const bool prerelease = false;

        var packages = repository.GetPackages()
            .Where(p => prerelease ? p.IsAbsoluteLatestVersion : p.IsLatestVersion)
            .Where(p => VersionUtility.IsCompatible(frameworkName, p.GetSupportedFrameworks()));

        foreach (IPackage package in packages)
        {
            GetValue(repository, frameworkName, package, prerelease, 0);
        }

        Console.WriteLine();
        Console.WriteLine("Press Enter...");
        Console.ReadLine();
    }

    private static void GetValue(IPackageRepository repository, FrameworkName frameworkName, IPackage package, bool prerelease, int level)
    {

        Console.WriteLine("{0}{1}", new string(' ', level * 3), package);
        foreach (PackageDependency dependency in package.GetCompatiblePackageDependencies(frameworkName))
        {
            IPackage subPackage = repository.ResolveDependency(dependency, prerelease, true);
            GetValue(repository, frameworkName, subPackage, prerelease, level + 1);
        }
    }
}

If you're using the new .csproj, you could get all dependencies with reference in here (after project built):

{ProjectDir}\obj\project.assets.json

enter image description here


It is also possible to write code against the API in NuGet.Core. Install it via NuGet:

install-package nuget.core

Then you can get a repository object and walk the graph. Here's a sample app I just built:

using System;
using System.Collections.Generic;
using System.Linq;
using NuGet;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main()
        {    
            var repo = new LocalPackageRepository(@"C:\Code\Common\Group\Business-Logic\packages");
            IQueryable<IPackage> packages = repo.GetPackages();
            OutputGraph(repo, packages, 0);
        }

        static void OutputGraph(LocalPackageRepository repository, IEnumerable<IPackage> packages, int depth)
        {
            foreach (IPackage package in packages)
            {
                Console.WriteLine("{0}{1} v{2}", new string(' ', depth), package.Id, package.Version);

                IList<IPackage> dependentPackages = new List<IPackage>();
                foreach (var dependency in package.Dependencies)
                {
                    dependentPackages.Add(repository.FindPackage(dependency.Id, dependency.VersionSpec.ToString()));
                }

                OutputGraph(repository, dependentPackages, depth += 3);
            }
        }
    }
}

In my case, this app outputs something like this:

MyCompany.Castle v1.1.0.3
   Castle.Windsor v2.5.3
      Castle.Core v2.5.2
      MyCompany.Common v1.1.0.6
         CommonServiceLocator v1.0
            MyCompany.Enum v1.1.0.7
   MyCompany.Common v1.1.0.6
      CommonServiceLocator v1.0
         MyCompany.Enum v1.1.0.7
      MyCompany.Enum v1.1.0.7
         MyCompany.Versioning v1.3
            Castle.Core v2.5.2
               Castle.Windsor v2.5.3
                  Castle.Core v2.5.2
                  CommonServiceLocator v1.0
                     NUnit v2.5.10.11092
                        RhinoMocks v3.6

I've found a nice NPM package to print the dependency tree into console. Of course if you don't mind using/installing NPM/Node.JS.

Considering other solutions, this is the most simple one, you don't need to write your own code or register something, and you get just such dependency tree as you expect. But it works only with packages.config format.

I can't believe this functionality is absent in free Visual Studio editions or nuget.exe too.