Dependency graph of Visual Studio projects

前端 未结 16 2284
鱼传尺愫
鱼传尺愫 2020-11-28 17:42

I\'m currently migrating a big solution (~70 projects) from VS 2005 + .NET 2.0 to VS 2008 + .NET 3.5. Currently I have VS 2008 + .NET 2.0.

The problem is that I need

相关标签:
16条回答
  • 2020-11-28 18:15

    This extended version of the PS Script from Danny Tuppeny shows references for both csproj and vcxproj files, and also supports

    -Depth - maximum dependency chain length

    -Like - prints only dependency chains starting with projects with name -like $Like

    -UntilLike - cuts dependency chains on projects with name -like $UntilLike

    -Reverse - prints reversed dependency chains ([proj] <- [referencing proj])

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false)]
        [string]$RootFolder = ".",
        [Parameter(Mandatory=$false)]
        [string]$Like = "*",
        [Parameter(Mandatory=$false)]
        [string]$UntilLike = "*",
        [Parameter(Mandatory=$false)]
        [switch]$Reverse,
        [Parameter(Mandatory=$false)]
        [int]$Depth=1
    )
    
    $arrow = if ($script:Reverse) { "<-" } else { "->" }
    
    Function PrintTree ($projectNameToProjectNameList, $projectName, $maxDepth = 1, $prefix = "")
    {
        $print = $script:UntilLike -eq "*" -or $projectName -Like $script:UntilLike
        $stop = $projectNameToProjectNameList[$projectName].count -eq 0 -or $maxDepth -eq 0 -or ($script:UntilLike -ne "*" -and $projectName -Like $script:UntilLike)
        
        if ($stop) {
            if ($print) {
                $prefix + "[$projectName]"
            }
        } else {
            $prefix += "[$projectName] $arrow "
            --$maxDepth
            $projectNameToProjectNameList[$projectName] | % { PrintTree $projectNameToProjectNameList $_ $maxDepth $prefix }
        }
    }
    
    Function Get-ProjectReferences ($rootFolder)
    {
        $projectFiles = Get-ChildItem $rootFolder -Filter *.csproj -Recurse
        $projectFiles += Get-ChildItem $rootFolder -Filter *.vcxproj -Recurse
        $ns = @{ defaultNamespace = "http://schemas.microsoft.com/developer/msbuild/2003" }
        
        $projectGuidToProjectName = @{}
        $projectNameToProjectReferenceGuidList = @{}
    
        $projectFiles | ForEach-Object {
            $projectFile = $_ | Select-Object -ExpandProperty FullName
            $projectName = $_ | Select-Object -ExpandProperty BaseName
            $projectXml = [xml](Get-Content $projectFile)
            
            $projectGuid = $projectXml | Select-Xml '//defaultNamespace:ProjectGuid' -Namespace $ns | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty "#text" | % { $_ -as [Guid] }
            $projectGuidToProjectName[$projectGuid] = $projectName
    
            $projectReferenceGuids = $projectXml | Select-Xml '//defaultNamespace:ProjectReference/defaultNamespace:Project' -Namespace $ns | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty "#text" | % { $_ -as [Guid] }
            if ($null -eq $projectReferenceGuids) { $projectReferenceGuids = @() }
            $projectNameToProjectReferenceGuidList[$projectName] = $projectReferenceGuids
        }
    
        $projectNameToProjectReferenceNameList = @{}
        foreach ($projectName in $projectNameToProjectReferenceGuidList.keys) {
            $projectNameToProjectReferenceNameList[$projectName] = $projectNameToProjectReferenceGuidList[$projectName] | % { $projectGuidToProjectName[$_] } | sort
        }
        
        if ($script:Reverse) {
            $projectReferenceNameToProjectNameList = @{}
            foreach ($projectName in $projectNameToProjectReferenceNameList.keys) {
                foreach ($projectReferenceName in $projectNameToProjectReferenceNameList[$projectName]) {
                    if (!$projectReferenceNameToProjectNameList.ContainsKey($projectReferenceName)) { $projectReferenceNameToProjectNameList[$projectReferenceName] = @() } 
                    $projectReferenceNameToProjectNameList[$projectReferenceName] += $projectName
                }
            }
    
            foreach ($projectName in $projectReferenceNameToProjectNameList.keys -Like $script:Like) {
                PrintTree $projectReferenceNameToProjectNameList $projectName $script:Depth
            }
        } else {
            foreach ($projectName in $projectNameToProjectReferenceNameList.keys -Like $script:Like) {
                PrintTree $projectNameToProjectReferenceNameList $projectName $script:Depth
            }
        }
    }
    
    Get-ProjectReferences $RootFolder
    
    0 讨论(0)
  • 2020-11-28 18:20

    If you simply want a dependency graph I've found this is one of the cleanest ways to get one:

    Dependency Analyser

    0 讨论(0)
  • 2020-11-28 18:20

    If you're looking for a way that doesn't require any external tools, you can navigate to a project's obj/project.assets.json file. This file is generated during build, and has a hierarchical JSON structure of the dependencies (both project references and nuget packages).

    It's useful for answering questions like "why the hell is this project DLL being pulled into the build directory?"

    0 讨论(0)
  • 2020-11-28 18:22

    To complete the eriawan answer on graphs generated by NDepend see screenshoots below. You can download and use the free trial edition of NDepend for a while.

    More on NDepend Dependency Graph enter image description here

    More on NDepend Dependency Matrix: enter image description here

    Disclaimer: I am part of the tool team

    0 讨论(0)
  • 2020-11-28 18:25

    The Powershell solution is the best. I adapted it into a bash script that works on my machine (TM):

    #!/bin/bash
    
    for i in `find . -type f -iname "*.csproj"`; do
        # get only filename
        project=`basename $i`
    
        # remove csproj extension
        project=${project%.csproj}
    
        references=`cat $i | grep '<ProjectReference' | cut -d "\"" -f 2`
        for ref in $references; do
            # keep only filename (assume Windows paths)
            ref=${ref##*\\}
    
            # remove csproj extension
            ref=${ref%.csproj}
    
            echo "[ $project ] -> [ $ref ]"
        done
    
    done
    
    0 讨论(0)
  • 2020-11-28 18:28

    Have you tried NDepend? It'll shows you the dependencies and you can also analyze the usability of your classes and methods.

    Their website:

    http://ndepend.com


    To complete the @Eriawan answer in April 2020 NDepend version 2020.1 has been released with Dependency Graph completely rebuilt. It now scales on large solutions made of hundreds of projects and offers many navigation facilities.

    Here is what it looks like on the NopCommerce OSS project.

    Here is what it looks like on the entire .NET Core 3 classes library (176 assemblies).

    Disclaimer: I work at NDepend

    0 讨论(0)
提交回复
热议问题