Friday, 29 April 2016

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.

No comments: