.NET Core Dependency Tree
Asked Answered
A

5

17

Is it possible to view dependencies for a project in a .NET core application? I'm using Visual Studio 2017 Professional.

At the moment I have the following Nuget packages referenced in my csproj.

<ItemGroup>
    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.1" />
    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Identity" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.2" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.1" />
    <PackageReference Include="SimpleInjector.Integration.AspNetCore.Mvc" Version="4.0.8" />
</ItemGroup>

Where you can navigate dependencies.

dependencies

But it makes it hard to find a particular dependency - a tree is good if you know what you are looking for. Is there a way to output a flat list of dependant assemblies and there versions?

Adventitious answered 6/7, 2017 at 8:56 Comment(0)
A
28

You can add an msbuild target to your project file (inside the <Project> element) like this:

<Target Name="PrintAllReferences" DependsOnTargets="RunResolvePackageDependencies">
  <Message Importance="high" Text="Referenced package: %(PackageDefinitions.Identity)" />
</Target>

Which you can call like this (a line without a parent package name means it is referenced by the project directly):

$ dotnet msbuild /nologo /t:PrintAllReferences
  Referenced package: Microsoft.NETCore.Platforms/1.1.0
  Referenced package: Microsoft.NETCore.Targets/1.1.0
  Referenced package: Microsoft.Win32.Primitives/4.3.0
  Referenced package: NETStandard.Library/1.6.1
  Referenced package: runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0
  Referenced package: runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0
  Referenced package: runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0
  Referenced package: runtime.native.System/4.3.0
  Referenced package: runtime.native.System.IO.Compression/4.3.0
  Referenced package: runtime.native.System.Net.Http/4.3.0
  Referenced package: runtime.native.System.Security.Cryptography.Apple/4.3.0
  Referenced package: runtime.native.System.Security.Cryptography.OpenSsl/4.3.0
  Referenced package: runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0
  Referenced package: runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl/4.3.0
  Referenced package: System.Buffers/4.3.0
  Referenced package: System.Collections/4.3.0
  …

If you wanted a "reverse dependency tree" - a list of packages and which packages reference them - you can do something similar to:

<Target Name="PrintPackagesAndParents" DependsOnTargets="RunResolvePackageDependencies">
  <Message Importance="high" Text="* %(PackageDependencies.Identity) referenced by:%0a^---@(PackageDependencies->'%(ParentPackage) - target %(ParentTarget)', '%0a^---')" />
</Target>

which produces the following output:

$ dotnet msbuild /nologo /t:PrintPackagesAndParents
  * JetBrains.Annotations/10.2.1 referenced by:
  ^--- - target .NETStandard,Version=v1.3
  * System.IO.FileSystem.Primitives/4.0.1 referenced by:
  ^---NETStandard.Library/1.6.0 - target .NETStandard,Version=v1.3
  ^---System.IO.Compression.ZipFile/4.0.1 - target .NETStandard,Version=v1.3
  ^---System.IO.FileSystem/4.0.1 - target .NETStandard,Version=v1.3
  ^---System.Xml.ReaderWriter/4.0.11 - target .NETStandard,Version=v1.3
  * System.Linq/4.1.0 referenced by:
  ^---NETStandard.Library/1.6.0 - target .NETStandard,Version=v1.3
  ^---System.Security.Cryptography.Encoding/4.0.0 - target .NETStandard,Version=v1.3
  * System.Linq.Expressions/4.1.0 referenced by:
  ^---NETStandard.Library/1.6.0 - target .NETStandard,Version=v1.3
  * System.Net.Http/4.1.0 referenced by:
  ^---NETStandard.Library/1.6.0 - target .NETStandard,Version=v1.3
  * System.Net.Primitives/4.0.11 referenced by:
  ^---NETStandard.Library/1.6.0 - target .NETStandard,Version=v1.3
  ^---System.Net.Http/4.1.0 - target .NETStandard,Version=v1.3
  ^---System.Net.Sockets/4.1.0 - target .NETStandard,Version=v1.3
  …

There isn't really documentation about these items, but they have "public" name and are generated by the ResolvePackageDependencies task which is executed as part of the RunResolvePackageDependencies target and produces a few very useful items: TargetDefinitions, PackageDefinitions, PackageDependencies, FileDependencies and DiagnosticMessages.

Antalkali answered 6/7, 2017 at 9:12 Comment(7)
Ah, very nice. Also, if you save the command in a batch file called dotnet-printrefs.bat you'll be able to call it from the command line like this dotnet printrefsAutocatalysis
Oh, and put the batch file in C:\Program Files\dotnet and you can use it in any project tooAutocatalysis
Neat. Are there docs on this? What other information can you add? Can you get the full dependency tree output so you can see what the parent assembly is?Adventitious
Added an example for a reverse dependency tree and links to the source code. I don't think there is a good documentation about it though..Antalkali
I'm unable to get this to work with .NET Core 2.1+. My thoughts are that the target ResolvePackageDependenciesForBuild or ItemGroup PackageDefinitions might have changed names. I'm also not finding any documentation on msbuild targets in use by .NET Core. Anyone having the same issue?Hardspun
Ah yeah the resolution was revamped for 2.0, you'd now need to depend on RunResolvePackageDependencies AFAIKAntalkali
for dotnetcore 3.1+ you need to set 'EmitLegacyAssetsFileItems' to true learn.microsoft.com/en-us/dotnet/core/compatibility/msbuildHawkins
A
6

This flashed up today in the Morning Brew which might be worth a look:

Martin Bjorkstrom Dotnet Depends

Adventitious answered 10/8, 2018 at 12:45 Comment(0)
P
5

You can actually search through dependencies of particular project quite easily in Visual Studio.

Just right click on Dependencies, select "scope to this". And then you can directly search through dependencies. scope to this

Perseid answered 13/8, 2020 at 18:32 Comment(0)
V
3

In the dropdown if Search bar, tick Search within file contents and Search within external items, and enter the package you want to search to see the dependency tree if this package enter image description here

Volva answered 24/8, 2022 at 10:50 Comment(0)
U
3

You might find it easier to parse the output from the dotnet list package commands directly:

dotnet list package --include-transitive

It still separates per-csproj, but it keeps them in one "level", and the text is likely easier to parse:

dotnet list package --include-transitive

Project 'TestApp' has the following package references
   [net6.0]:
   Top-level Package         Requested             Resolved
   > System.CommandLine      2.0.0-beta1.21308.1   2.0.0-beta1.21308.1

   Transitive Package      Resolved
   > Crayon                2.0.62
   > SomeDep               1.0.0
   > Microsoft.CSharp      4.4.1
   > AnotherDep            1.0.0
   > System.Memory         4.5.4

// ...
Ulster answered 31/10, 2023 at 16:22 Comment(1)
I had not seen this option til today. Thank you ! (separation by csproj was key for me)Asha

© 2022 - 2024 — McMap. All rights reserved.