Wykres zależności projektów programu Visual Studio


136

Obecnie przeprowadzam migrację dużego rozwiązania (~ 70 projektów) z VS 2005 + .NET 2.0 do VS 2008 + .NET 3.5. Obecnie posiadam VS 2008 + .NET 2.0.

Problem polega na tym, że muszę przenosić projekty jeden po drugim do nowej platformy .NET, upewniając się, że żaden projekt .NET 2.0 nie odwołuje się do projektu .NET 3.5. Czy jest jakieś narzędzie, które dałoby mi ładny wykres zależności projektu?

Odpowiedzi:


42

Czy próbowałeś NDepend? Pokaże Ci zależności i możesz również przeanalizować użyteczność swoich klas i metod.

Ich strona internetowa:

http://ndepend.com


Aby uzupełnić odpowiedź @Eriawan w kwietniu 2020 roku, została wydana wersja NDepend 2020.1 z całkowicie przebudowanym wykresem zależności . Obecnie skaluje się na dużych rozwiązaniach złożonych z setek projektów i oferuje wiele udogodnień nawigacyjnych.

Oto jak to wygląda w projekcie NopCommerce OSS .

Wykres zależności NDepend w NopCommerce

Oto, jak to wygląda w całej bibliotece klas .NET Core 3 (176 zestawów).

wprowadź opis linku tutaj

Zastrzeżenie: pracuję w NDepend


4
oryginalny plakat nie mówił, że ndepend jest wolny i rozwiązuje problem.
krystan honor

6
W momencie pisania tej odpowiedzi mogło być za darmo, ale teraz tak nie jest.
Levente Koncz

1
@ patrick-from-ndepend-team Proszę nie edytować bezpośrednio mojej odpowiedzi i zamiast tego otwórz nową odpowiedź.
Eriawan Kusumawardhono

Ok @EriawanKusumawardhono przepraszam, jeśli to dla ciebie problem. W ten sposób czytelnicy otrzymają więcej szczegółów, a to poprawia użyteczność odpowiedzi. Czy chcesz, abym usunął dodatkowe szczegóły i zrzuty ekranu?
Patrick z zespołu NDepend

1
@PatrickfromNDependteam dodatkowe szczegóły i zrzuty ekranu są w porządku. ale ponieważ jest to pierwotnie moja odpowiedź, wygląda na to, że twoja edycja w jakiś sposób sprawia, że ​​wyglądam jak praca w NDepend. Dodaj nową odpowiedź do swojej zmiany, a także zaznacz, że Twoja nowa odpowiedź jest uzupełnieniem mojej odpowiedzi. Dzięki wcześniej :)
Eriawan Kusumawardhono

175

Potrzebowałem czegoś podobnego, ale nie chciałem płacić za (ani instalować) narzędzia do tego. I stworzył krótki skrypt PowerShell, który przechodzi przez odniesień projektowych i wyrzuca je w yuml.me przyjaznym formacie zamiast:

Function Get-ProjectReferences ($rootFolder)
{
    $projectFiles = Get-ChildItem $rootFolder -Filter *.csproj -Recurse
    $ns = @{ defaultNamespace = "http://schemas.microsoft.com/developer/msbuild/2003" }

    $projectFiles | ForEach-Object {
        $projectFile = $_ | Select-Object -ExpandProperty FullName
        $projectName = $_ | Select-Object -ExpandProperty BaseName
        $projectXml = [xml](Get-Content $projectFile)

        $projectReferences = $projectXml | Select-Xml '//defaultNamespace:ProjectReference/defaultNamespace:Name' -Namespace $ns | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty "#text"

        $projectReferences | ForEach-Object {
            "[" + $projectName + "] -> [" + $_ + "]"
        }
    }
}

Get-ProjectReferences "C:\Users\DanTup\Documents\MyProject" | Out-File "C:\Users\DanTup\Documents\MyProject\References.txt"

5
niesamowite. Wziąłem to i rozszerzyłem, aby przejść przez wszystkie projekty podrzędne, a następnie ponownie rozszerzyłem, aby zamiast tego pobrać plik sln, aby zmapować cały projekt. Dzięki
Jon

Z jakimi wersjami programu Visual Studio to działa? Ponadto, aby wizualizować projekty w C ++ zamiast C #, wystarczy zmienić sufiks pliku .csproj na .vcproj? Pracuję z VS 2005 tutaj i otrzymuję pusty plik wyników ...
ssc

1
Został napisany w oparciu o projekt z 2010 roku dla C #, ale prawdopodobnie można by go naprawdę łatwo poprawić, patrząc na XML wewnątrz projektu C ++ i dostosowując kod :-)
Danny Tuppeny

5
@ssc Na moim blogu opublikowano nieco zaktualizowany kod, który może być łatwiejszy do dostosowania: blog.dantup.com/2012/05/…
Danny Tuppeny

5
Jeśli używasz Powershell 2.0, musisz dołączyć =$truedo parametrów MandatoryiValueFromPipeline
MoMo

79

Aktualizacja: ReSharper od wersji 8 ma wbudowaną funkcję „Wyświetl zależności projektu” .

Wersja <8 ReSharper ma wewnętrzną funkcję pokazującą wykresy zależności w przeglądarce yFiles. Zobacz skróconą instrukcję na dole posta.

wprowadź opis obrazu tutaj

Jak

  1. Zainstaluj narzędzie YEd stąd .
  2. Uruchom VS z argumentem wiersza poleceń /resharper.internal.
  3. Przejdź do ReSharper / Internal / Show Dependencies.
  4. Określ projekty, które chcesz uwzględnić w „ogólnym obrazie”.
  5. Usuń zaznaczenie opcji „Wyklucz węzły terminala ...”, chyba że jest to potrzebne.
  6. Naciśnij „Pokaż”.
  7. Użyj układu hierarchicznego w yEd (Alt + Shift + H)
  8. Przekaż opinię =)

2
Również Resharper> Inspect> Project Hierarchy, aby uzyskać listę projektów, do których odwołuje się bieżący
Lu55

6
Resharper> Architektura> „Pokaż diagram zależności projektu”
Dr Blowhard

32

Możesz łatwo uzyskać wykres zależności projektu za pomocą Visual Studio 2010 Ultimate, zeskanuj ten film do 5 minut, aby zobaczyć, jak: http://www.lovettsoftware.com/blogengine.net/post/2010/05/27/Architecture-Explorer .aspx

W programie Visual Studio 2010 Ultimate: Architecture | Wygeneruj wykres zależności | Według montażu.


@CJohnson Możesz to zrobić dla kodu C i C ++, jeśli masz Visual Studio 2010 Feature Pack 2 . Zobacz także How to: Generate Dependency Graphs for C and C ++ Code
Esther Fan - MSFT

1
Próbowałem, rzuciłem wyjątek. Najwyraźniej MS nigdy nie testowało go z niczym poza kilkoma projektami. Moim zdaniem absolutnie bezwartościowe.
C Johnson,

1
Nie tylko to, jest też strasznie wolno. Zrobiłbym to -10, gdybym mógł. Napisałem własny walker zależności od projektu (dla naszego własnego systemu kompilacji) i był on błyskawiczny w porównaniu do tego w Visual Studio.
C Johnson,

@CJohnson Zgadzam się, że jest powolny i podatny na rzucanie wyjątków dla dużych rozwiązań, ale nadal jest lepszy niż nic. Uruchomiłem go, zamykając wszystkie aplikacje, zatrzymując niektóre usługi i ponownie uruchamiając Visual Studio.
WynandB

Dla mnie duże rozwiązania to około 600 projektów z milionami linii kodu. Nie ma szans, że zatrzymanie kilku usług jest dla mnie akceptowalnym obejściem.
C Johnson,

20

Napisałem narzędzie, które może ci pomóc. VS Solution Dependency Visualizer analizuje zależności projektów w ramach rozwiązania i tworzy wykres zależności na podstawie tych informacji, a także raport tekstowy.


Jakie wersje programu Visual Studio i jakiego rodzaju projekty to działa? VS 2005 / C ++ tutaj i wydaje się, że narzędzie nic nie robi ...
ssc

zdecydowanie działa z wersjami 2008/2010 i .csproj / .vbproj. nie testowałem z vs2005, ale obecnie pliki .vcproj nie są rozpoznawane
devio

To narzędzie pokazuje tylko plik rozwiązania po przeanalizowaniu go :-(. Nie moje około 300 projektów.
thersch

@thersch, jeśli chcesz, żebym go obejrzał, spakuj .sln i pliki projektu (aby zachować oryginalną strukturę katalogów), prześlij je do udziału plików i skontaktuj się ze mną za pośrednictwem mojego bloga. thx
devio

9

Miałem podobny problem, ale był on jeszcze bardziej skomplikowany, ponieważ kilka projektów odwoływało się do różnych wersji tego samego zestawu.

Aby uzyskać dane wyjściowe, które zawierają informacje o wersji i sprawdzają możliwe problemy z ładowaniem zestawu w czasie wykonywania, stworzyłem to narzędzie:

https://github.com/smpickett/DependencyViewer

(bezpośredni link do wersji na Github: https://github.com/smpickett/DependencyViewer/releases )


1
Niezłe narzędzie! Proste i wydajne. Dziękuję za to! +1 ode mnie.
Buka

Naprawdę świetne narzędzie! Marzyłem o czymś takim od lat. Bardzo dziękuję za udostępnienie!
alehro

8

Możesz utworzyć wykres zależności swoich projektów w VS 2010 Ultimate. Architecture Explorer umożliwia przeglądanie rozwiązania, wybieranie projektów i relacji, które chcesz wizualizować, a następnie tworzenie wykresu zależności na podstawie dokonanego wyboru.

Aby uzyskać więcej informacji, zobacz następujące tematy:

Instrukcje: generowanie dokumentów wykresów na podstawie kodu : http://msdn.microsoft.com/en-us/library/dd409453%28VS.100%29.aspx#SeeSpecificSource

Instrukcje: znajdowanie kodu za pomocą narzędzia Architecture Explorer : http://msdn.microsoft.com/en-us/library/dd409431%28VS.100%29.aspx

Pobieranie RC : http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=457bab91-5eb2-4b36-b0f4-d6f34683c62a .

Forum narzędzi do wykrywania i modelowania architektury programu Visual Studio 2010 : http://social.msdn.microsoft.com/Forums/en-US/vsarch/threads


VS 2012 Professional też? A może tylko VS 2012 Ultimate?
Kiquenet,

@Kiquenet Możesz tworzyć wykresy zależności w VS 2012 Ultimate. Możesz otwierać i wprowadzać ograniczone zmiany w Premium i Pro.
Esther Fan - MSFT

5

Aby uzupełnić odpowiedź eriawan na wykresach generowanych przez NDepend, zobacz poniższe zrzuty ekranu. Możesz pobrać bezpłatną wersję próbną NDepend i korzystać z niej przez chwilę.

Więcej na temat wykresu zależności NDepend wprowadź opis obrazu tutaj

Więcej o macierzy zależności NDepend : wprowadź opis obrazu tutaj

Zastrzeżenie: jestem częścią zespołu narzędziowego


NDepend jest dla .NET, jego klon CppDepend jest dla C ++ i współpracuje z plikami .vcxproj
Patrick z zespołu NDepend

5

Rozwiązanie Powershell jest najlepsze. Zaadaptowałem go do skryptu bash, który działa na moim komputerze (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



3

W programie VS 2019 zmieniono nazwę modułu wykresu zależności na Code Map

tutaj jest oficjalna dokumentacja: https://docs.microsoft.com/en-us/visualstudio/modeling/map-dependencies-across-your-solutions?view=vs-2019


„Aby tworzyć i edytować mapy kodu, potrzebujesz wersji Visual Studio Enterprise. W wersjach Visual Studio Community i Professional można otwierać diagramy, które zostały wygenerowane w wersji Enterprise, ale nie można ich edytować”.
MatthewT

1

Ta rozszerzona wersja skryptu PS autorstwa Danny'ego Tuppeny'ego zawiera odniesienia do projektu i zewnętrzne:

Function Get-ProjectReferences($rootPath)
{
  $projectFiles = Get-ChildItem $rootPath -Filter *.csproj -Recurse
  $ns = @{ defaultNamespace = "http://schemas.microsoft.com/developer/msbuild/2003" }

  $projectFiles | ForEach-Object {
    $projectFile = $_ | Select-Object -ExpandProperty FullName
    $projectName = $_ | Select-Object -ExpandProperty BaseName
    $projectXml = [xml](Get-Content $projectFile)

    $projectReferences = $projectXml | Select-Xml '//defaultNamespace:ProjectReference/defaultNamespace:Name' -Namespace $ns | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty "#text"
    $projectReferences | ForEach-Object {
        "PR:[" + $projectName + "]:[" + $_ + "]"
    }
  }

  $projectFiles | ForEach-Object {
    $projectFile = $_ | Select-Object -ExpandProperty FullName
    $projectName = $_ | Select-Object -ExpandProperty BaseName
    $projectXml = [xml](Get-Content $projectFile)

    $externalReferences = $projectXml | Select-Xml '//defaultNamespace:Reference/@Include' -Namespace $ns
    $externalReferences | ForEach-Object {
        "ER:[" + $projectName + "]:[" + $_ + "]"
    }

  }

}

Get-ProjectReferences "C:\projects" | Out-File "C:\temp\References.txt"

Daje plik rozdzielony dwukropkami, który można otworzyć i przeanalizować w programie Excel.


0

Ta rozszerzona wersja skryptu PS autorstwa Danny'ego Tuppeny'ego pokazuje odniesienia do plików csproj i vcxproj , a także obsługuje

-Depth - maksymalna długość łańcucha zależności

-Like - wyświetla tylko łańcuchy zależności zaczynające się od projektów o nazwie -jak $ Like

-UntilLike - ucina łańcuchy zależności w projektach o nazwie $ UntilLike

-Reverse - wyświetla odwrócone łańcuchy zależności ( [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

Jeśli szukasz sposobu, który nie wymaga żadnych zewnętrznych narzędzi, możesz przejść do obj/project.assets.jsonpliku projektu . Ten plik jest generowany podczas kompilacji i ma hierarchiczną strukturę JSON zależności (zarówno odwołania do projektu, jak i pakiety nuget).

Jest to przydatne do odpowiadania na pytania typu „dlaczego do cholery ta biblioteka DLL projektu jest wciągana do katalogu kompilacji?”


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.