When a code project grows complex it's going to be difficult to understand which depends on which - developers familiar with the C# ecosystem can look at NuGet Package Manager and use .csproj
to try to study things but when the hierarchy gets complex it can feel inconvenient.
For instance, say I have a top-level entry program that I know ultimately depends on Mathnet.Numerics
- now I need to figure out which subproject references it.
The General Approach
To view which project depend on which package in C#, below are some approaches using existing tools.
1. Using the .NET CLI
This approach only shows the NuGet packages the projects depend on.
a) List packages per project
Run, for each project:
dotnet list path/to/MyProject.csproj package
We'll get an "Installed" section showing direct references.
b) Include transitive dependencies
dotnet list path/to/MyProject.csproj package --include-transitive
This will also show packages pulled in by other packages.
c) Script it for the entire solution
On bash (Linux/macOS/git-bash):
for proj in $(find . -name '*.csproj'); do
echo "== $proj =="
dotnet list "$proj" package --include-transitive | grep MathNet.Numerics -B2 -A2
done
On PowerShell (Windows):
Get-ChildItem -Recurse -Filter *.csproj |
ForEach-Object {
Write-Host "== $($_.FullName) =="
dotnet list $_.FullName package --include-transitive |
Select-String "MathNet.Numerics" -Context 2,2
}
2. Grep / Select-String on .csproj
files
Since NuGet package references live in <PackageReference>
items, we can search directly:
- bash:
grep -R "PackageReference.*MathNet\.Numerics" -n .
- PowerShell:
Get-ChildItem -Path . -Filter *.csproj -Recurse | Select-String -Pattern 'MathNet\.Numerics' -List
# Or
Get-ChildItem -Recurse -Filter *.csproj | Select-String -SimpleMatch 'MathNet.Numerics' -List
That will show us exactly which project files reference it.
Alternatively, just do a full text search in VS Code with file type filter.
3. Visual Studio / Rider UI
- Right-click on the Solution → Manage NuGet Packages for Solution…
- Go to the Installed tab, find MathNet.Numerics in the left panel.
- On the right, we'll see checkboxes or project-scoped lists showing which projects have it installed.
Once again, this method doesn't show the complete picture or the hierarchy of dependencies.
4. MSBuild Dependency Graph (advanced)
If we need to audit transitive and project-to-project dependencies in one go, we can generate a restore graph:
dotnet msbuild /t:GenerateRestoreGraphFile /p:RestoreGraphOutputPath=graph.dg
This produce a fairly comprehensive output that contains absolute paths and a bit too much irrelevant information.
Then inspect graph.dg
(JSON) for entries where "PackageId":"MathNet.Numerics"
and note the "ProjectPath"
fields.
Custom Tool
Above methods work but if you don't like the output format, CLI syntax, or just want something more straightforward - then it's time for a custom tool.
The C# Dependency Analyzer is a tool that can quickly help identify dependencies of a source code project. This is useful in identifying unwanted nuget dependencies from any given entry assembly. It is equivalent to manually searching through .csproj to find which projects depend on which and debug NuGet dependencies.
It can do those three things:
- Print an exhaustive dependency tree with a root node at each source project level down to all dependent projects and most importantly the root NuGets
- Given a single target project/nuget, prints a filtered tree of all projects that depend on that assembly
- Given a single target project/nuget and a source assembly, it prints the tree paths that lead from the source assembly to the target - showing clearly the path from the source assembly to the ultimate dependency.
Below is an example output with command: path --path <solution path> --source Transcriber --target SkiaSharp
References
- Methodox Dependency analyzer: visit Github
Top comments (0)