<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged nuget</title>
<link>https://coderlegion.com/tag/nuget</link>
<description>Powered by Question2Answer</description>
<item>
<title>DevLog 20250706: Analyzing (C#) Project Dependencies</title>
<link>https://coderlegion.com/3738/devlog-20250706-analyzing-c-project-dependencies</link>
<description>&lt;p&gt;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 &lt;code&gt;.csproj&lt;/code&gt; to try to study things but when the hierarchy gets complex it can feel inconvenient.&lt;/p&gt;
&lt;p&gt;For instance, say I have a top-level entry program that I know ultimately depends on &lt;code&gt;Mathnet.Numerics&lt;/code&gt; - now I need to figure out which subproject references it.&lt;/p&gt;
&lt;h3 id=&quot;the-general-approach&quot;&gt;The General Approach&lt;/h3&gt;
&lt;p&gt;To view which project depend on which package in C#, below are some approaches using existing tools.&lt;/p&gt;
&lt;h4 id=&quot;1-using-the-net-cli&quot;&gt;1. Using the .NET CLI&lt;/h4&gt;
&lt;p&gt;This approach only shows the NuGet packages the projects depend on.&lt;/p&gt;
&lt;h5 id=&quot;a-list-packages-per-project&quot;&gt;a) List packages per project&lt;/h5&gt;
&lt;p&gt;Run, for each project:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet list path/to/MyProject.csproj package
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We'll get an &lt;em&gt;&quot;Installed&quot;&lt;/em&gt; section showing direct references.&lt;/p&gt;
&lt;h5 id=&quot;b-include-transitive-dependencies&quot;&gt;b) Include transitive dependencies&lt;/h5&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet list path/to/MyProject.csproj package --include-transitive
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will also show packages pulled in by other packages.&lt;/p&gt;
&lt;h5 id=&quot;c-script-it-for-the-entire-solution&quot;&gt;c) Script it for the entire solution&lt;/h5&gt;
&lt;p&gt;On &lt;strong&gt;bash&lt;/strong&gt; (Linux/macOS/git-bash):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;for proj in $(find . -name '*.csproj'); do
  echo &quot;== $proj ==&quot;  
  dotnet list &quot;$proj&quot; package --include-transitive | grep MathNet.Numerics -B2 -A2
done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On &lt;strong&gt;PowerShell&lt;/strong&gt; (Windows):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;Get-ChildItem -Recurse -Filter *.csproj |
  ForEach-Object {
    Write-Host &quot;== $($_.FullName) ==&quot;
    dotnet list $_.FullName package --include-transitive |
      Select-String &quot;MathNet.Numerics&quot; -Context 2,2
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;2-grep-select-string-on-csproj-files&quot;&gt;2. Grep / Select-String on &lt;code&gt;.csproj&lt;/code&gt; files&lt;/h4&gt;
&lt;p&gt;Since NuGet package references live in &lt;code&gt;&amp;lt;PackageReference&amp;gt;&lt;/code&gt; items, we can search directly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bash&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;grep -R &quot;PackageReference.*MathNet\.Numerics&quot; -n .
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PowerShell&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;Get-ChildItem -Path . -Filter *.csproj -Recurse | Select-String -Pattern 'MathNet\.Numerics' -List
  
# Or
Get-ChildItem -Recurse -Filter *.csproj | Select-String -SimpleMatch 'MathNet.Numerics' -List
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That will show us exactly which project files reference it.&lt;/p&gt;
&lt;p&gt;Alternatively, just do a full text search in VS Code with file type filter.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8u46rq4ltd19lj807dg.png&quot; alt=&quot;Search in VS Code&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;3-visual-studio-rider-ui&quot;&gt;3. Visual Studio / Rider UI&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Right-click&lt;/strong&gt; on the &lt;strong&gt;Solution&lt;/strong&gt; → &lt;strong&gt;Manage NuGet Packages for Solution…&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Go to the &lt;strong&gt;Installed&lt;/strong&gt; tab, find &lt;strong&gt;MathNet.Numerics&lt;/strong&gt; in the left panel.&lt;/li&gt;
&lt;li&gt;On the right, we'll see checkboxes or project-scoped lists showing which projects have it installed.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once again, this method doesn't show the complete picture or the hierarchy of dependencies.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6jjn66fa19sld80ymobr.png&quot; alt=&quot;Manage NuGets for Entire Solution&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;4-msbuild-dependency-graph-advanced-&quot;&gt;4. MSBuild Dependency Graph (advanced)&lt;/h4&gt;
&lt;p&gt;If we need to audit &lt;strong&gt;transitive&lt;/strong&gt; and &lt;strong&gt;project-to-project&lt;/strong&gt; dependencies in one go, we can generate a restore graph:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet msbuild /t:GenerateRestoreGraphFile /p:RestoreGraphOutputPath=graph.dg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This produce a fairly comprehensive output that contains absolute paths and a bit too much irrelevant information.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qzkdw17u1njkamxsekus.png&quot; alt=&quot;graph.dh&quot;&gt;&lt;/p&gt;
&lt;p&gt;Then inspect &lt;code&gt;graph.dg&lt;/code&gt; (JSON) for entries where &lt;code&gt;&quot;PackageId&quot;:&quot;MathNet.Numerics&quot;&lt;/code&gt; and note the &lt;code&gt;&quot;ProjectPath&quot;&lt;/code&gt; fields.&lt;/p&gt;
&lt;h3 id=&quot;custom-tool&quot;&gt;Custom Tool&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;The &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/MethodoxTech/Mirror_Tool_CSharpDependencyAnalyzer&quot;&gt;C# Dependency Analyzer&lt;/a&gt; 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.&lt;/p&gt;
&lt;p&gt;It can do those three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;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&lt;/li&gt;
&lt;li&gt;Given a single target project/nuget, prints a filtered tree of all projects that depend on that assembly&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Below is an example output with command: &lt;code&gt;path --path &amp;lt;solution path&amp;gt; --source Transcriber --target SkiaSharp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/phyw6tk6u14u30hit0l6.png&quot; alt=&quot;Dependency look up&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Methodox Dependency analyzer: visit &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/MethodoxTech/Mirror_Tool_CSharpDependencyAnalyzer&quot;&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>C#</category>
<guid isPermaLink="true">https://coderlegion.com/3738/devlog-20250706-analyzing-c-project-dependencies</guid>
<pubDate>Sun, 06 Jul 2025 19:26:37 +0000</pubDate>
</item>
</channel>
</rss>