• Analysing .NET code dependencies–Visual Studio Code Maps

    This is the second in a series of posts on reviewing tools to help analyse code dependencies in .NET

    Code Maps is a feature that was first included in Visual Studio 2012 Ultimate. It remains an Enterprise-only feature in 2015, though Professional and Community editions can view previously created diagrams.

    Code Maps operate from the cross-project solution level right down to the method level.

    Dependencies

    To generate a map of project dependencies, go to the Architecture menu, and choose Generate Code Map for Solution.

    A new window opens and gradually items appear on the diagram. Usually this will trigger a build of the solution, and then the analysis process will run, eventually displaying the dependencies between the projects.

    Code Maps - Solution

    If your solution uses solution folders to group similar projects, then you’ll see that represented in the diagram (the OLW solution doesn’t currently do this).

    You can then expand this out by selecting all the nodes (Ctrl-A) and choosing Group, Expand from the context menu.

    Code Maps - Solution expanded with externals highlighted

    You can see two things – the OpenLiveWriter.PostEditor project seems to be the most significant project, and also there’s an ‘Externals’ block with all external assembly references. To just focus on strictly code from the solution, you can select this group and press Delete. This removes it from the diagram.

    Editing a Code Map diagram doesn’t mess with your source code, as the diagrams are a bit like a snapshot of your code at the time they were created. In some ways this is a limitation, but one positive aspect is that you can use Code Map diagrams to model or prototype changes to the class hierarchy and dependencies without having to commit those changes in code.

    Let’s focus in on the PostEditor project. If we select that node, we can choose New Graph from the context menu. A separate diagram is now displayed with just the contents of the previously selected node. You can use the Filters tool window to select which elements you want to display. I de-selected Assembly so that I can now focus on the namespaces.

    Code Maps - HtmlEditor assembly classes

    Let’s keep going further in. Select the OpenLiveWriter.PostEditor namespace, and open this in a new graph again. To drill down to the class level, select all nodes again (Ctrl-A) and choose Group, Expand again.

    Code Maps - OpenLiveWriter.HtmlEditor namespace classes

    Let’s click on that top node – BlogPostEditingManager. Repeating the same process again, and filtering down to just methods, we get the following:

    Code Maps - BlogPostEditingManager Methods

    We now have a call graph of the methods inside the class. I also changed the layout for this graph to be ‘left to right’. The two blue nodes represent classes defined inside this class.

    Usually, you’d expect to see public methods on the left, and non-public methods going to the right. Unfortunately there’s no way distinguish between them apart from hovering over a node and reading the tooltip that appears, or by selecting a node and reviewing the details in the Properties window.

    Debugging

    You can also display Code Maps while debugging. If you have stopped at a breakpoint, you can right-click and select Show Call Stack on Code Map.

    Code Maps - Call stack

    Basically just a different way see the same info that gets displayed in the Call Stack debugging window, and unless I’ve missed something obvious, I think I’ll stick with the latter.

    Summary

    That’s a quick overview of some of the things that Code Maps can show you. They are entirely visual, so unlike NDepend, there’s no way to do any custom querying out of the box. On the other hand, the fact that the diagrams use DGML (directed graph markup language), it would be possible to write code that queried the file directly.

  • Analysing .NET code dependencies–NDepend

    This is the first in a series of posts on reviewing tools for analysing .NET code dependencies.

    I last wrote about NDepend briefly four years ago, and with a bit more detail way back in 2010. Some of the features added since then include:

    • Support for Visual Studio 2013 and 2015
      • Now a proper VSIX extension (v6)
      • NDepend project can be included in VS solution.
    • New Dashboard Panel – state of your code base at a glance
    • Focus on recent rules violations – only show rule violations on added/modified code
    • UI enhancements – improved menus
    • Better path management – UNC paths and support for environment and MSBuild variables.
    • Windows Store and Windows Phone support – honours the TypeForwardedToAttribute
    • Trend monitoring – monitor trend metrics and view via trend charts
    • Share rules between projects
    • Rules
      • Rule descriptions and fix suggestions added
      • Reduction in false positive detection
    • TFS integration
      • 2013 (2015 is coming)
    • SonarQube integration
    • TeamCity integration
    • Report enhancements – report includes trend metric charts
    • More console options – additional parameters to support file and directory variables.
    • Coloured Code Metric view – treemap elements can be coloured to indicate second metric
    • Code coverage shown with red/green colouring
    • Improved handling of compiler-generated code
    • Async support
    • High DPI support
    • Visual Studio theme support

    So let’s take NDepend v6 for a spin and see what it can do.

    I’m going to use the Open Live Writer code base for these reviews. The writer.sln contains 28 projects and around 3,000 types.

    The OLW solution is special in that most projects point to the same single output folder. As a result you might have to tell NDepend to look in this output directory rather than just relying on it to examine the solution’s projects. Once the assemblies are selected, the analysis begins.

    Analysis might take a minute or two, but when it finishes you are prompted to view the results. I chose the Dashboard view:

    NDepend Dashboard view

    To dig into the dependencies, let’s look at some useful diagrams. First up, the Dependency Graph. Go to NDepend, Graph, View Application Assemblies Only.

    Assembly dependency graph

    By default, the size of each ‘node’ indicates the relative number of IL instructions in that assembly. From the graph above, it’s obvious that OpenLiveWriter.PostEditor is the largest assembly. That sounds reasonable given that OLW is all about editing posts.

    Switching to the Matrix, here again is the ‘Application Assemblies Only’ view:

    Matrix View of Dependencies

    The intersections where there are 0 methods used from the assembly reference bear further investigation. Sometimes there might be a valid reason, but quite often this represents an unnecessary assembly reference that can be removed.

    The query language is very powerful. I’d like to find assemblies that are only referenced by one other assembly. Matching assemblies could be candidates for merging with the parent assembly if there’s no good reason for keeping them separate.

    I came up with this custom query:

    
    from m in Assemblies.ExceptThirdParty()
    where m.AssembliesUsingMe.Count() == 1
    select new { Parent = m.AssembliesUsingMe.First() , Child = m}
    

    Which returned the following results:

    • OpenLiveWriter.FileDestinations
    • OpenLiveWriter.HtmlEditor
    • OpenLiveWriter.InternalWriterPlugin

    Are all referenced only by OpenLiveWriter.PostEditor. That’s useful to know.

    Jumping back to the dashboard, let’s drill in to see some of those “Critical Rules Violated”. Clicking on this heading in the dashboard opens the Queries and Rules Explorer, with the “14 Critical Rules Violated” filter selected.

    Selecting the top item in the list opens the Queries and Rules Edit window, with the top half showing the actual query that was used to search for the violations and the bottom half showing a tree of matches for this rule (in this case it’s the offending methods). So that Init() method takes 15 parameters. Maybe that’s ok, maybe not.

    NDepend Queries and Rules Edit

    I love digging around the results of these kinds of rule queries. Particularly the ones around potential dead code, where you end up identifying and removing code that isn’t being used anymore.

    NDepend has really progressed over the years. It’s particularly nice to see the improved integration with Visual Studio. Ideally every developer would have NDepend in their toolbox to use themselves, but a first step is probably including it as part of your build pipeline. That way, at least everyone can view the reports it generates as part of the build results.

  • Analysing .NET code dependencies–Overview

    How can you tell if modules/components in your application are loosely-coupled between each other, and tightly cohesive internally? You could read the code line-by-line, but that becomes difficult once the codebase becomes large.

    It can be very valuable to be able to visualise the the dependencies between the various components that make up your application – both at the class and module/assembly level. These tools analyse code, either by parsing the source code, or by analysing the compiled assemblies to produce various summaries and reports about the state of the code.

    I’m planning to spend a bit of time in future blog posts reviewing a number of these tools that can help with this analysis, including:

    I’m also interested to hear what you use. Let me know in the comments of your experiences with these or other tools I haven’t mentioned.