Exploring Existing Code Architecture in Visual Studio through Dependency GraphThanks to the collaboration of...
NDepend Dependency Graph (4 minutes)
By default, the NDepend dependency graph panel displays the graph of dependencies between .NET assemblies:
NDepend proposes to explore the graph of dependencies between namespaces of a Visual Studio project.
In the Solution Explorer (or Code Editor window) right-click menu, NDepend proposes to explore the graph of dependencies between types of a namespace. Notice that NDepend comes with an heuristic to try to infer a namespace from a folder in Solution Explorer.
In the Solution Explorer (or Code Editor window) right-click menu, NDepend proposes to explore the graph of dependencies between members (methods + fields) of a type. Notice that NDepend comes with an heuristic to try to infer a type from a source file in Solution Explorer.
NDepend can generate any call graph you might need with a two steps procedure.
Class Inheritance Graph
To display a Class of Inheritance Graph, the same two steps procedure shown in the precedent section (on generating a Call Graph) must be applied.
It might be needed to know which code elements exactly are involved in a particular dependency. Especially when one needs to anticipate the impact of a structural change. In the screenshoot below, the NDepend Info panel describes a coupling between 2 assemblies.
From pointing a cell in the dependency matrix, it says that X types of an assembly A are using Y types of an assembly B. Notice that you can change the option Weight on Cell to # methods, # members or # namespaces, if you need to know the coupling with something else than types.
Just left clicking the matrix cell shows the coupling graph below.
A coupling graph can also be generated from an edge in the dependency graph. Here, you can adjust the option Edge Thickness to something else than # type.
If you wish to dig into a path or a dependency cycle between 2 code elements, the first thing to do is to show the dependency matrix with the option Weight on Cells: Direct & indirect depth of use.
Matrix blue and green cells will represent paths while black cells will represent dependency cycles. For example, here, the Info panel tells us that there is a path of minimal length 6 between the 2 types involved.
Just left clicking the cell shows the path graph below.
All Paths Graph
In certain situations, you'll need to know about all paths from a code element A to a code element B. For example, here, the Info panel tells us that there is a path of minimal length 2 between the 2 types involved.
Right clicking the matrix's cell and selecting the option Edit a code query that matches paths generatesthe following CQLinq query that matchs all types involved in all paths from type A to type B.
from t in Types
Finally exporting to the graph the 12 types matched by the CQLinq query, shows all paths from A to B.
As we explained in the previous section, to deal with dependency cycle graphs, the first thing to do is to show the dependency matrix with the option Weight on Cells: Direct & indirect depth of use. Black cells then represent cycles.
For example, here, the Info panel tells us that there is a dependency cycle of minimal length 5 between the 2 types involved.
Just left clicking the cell shows the cycle graph below.
We'd like to warn that obtaining a clean 'rounded' dependency cycle as the one shown above, is actually more an exceptional situation than a rule.
Often, exhibiting a cycle will end up in a not 'rounded' graph as the one shown below. In this example, the minimal length of a cycle between the 2 types involved (in yellow) is 12. Count the number of edges crossed from one yellow type to the other one, and you'll get 12. You'll see that some edges will be counted more than once.
Large Graph visualized with Dependency Structure Matrix
Here, we'd like to underline the fact that when the dependency Graph becomes unreadable, it is worth switching to the dependency Matrix.
Both dependency Graph and dependency Matrix co-exist because: