Disclaimer : My license for NDepend was provided free by Patrick Smacchia at NDepend. This license was not given to me in return for a good review. The article below is based purely on my own observations and use of NDepend.
A while back I published a couple of articles on Structured Code Reviews:
In these articles I discussed a code reviewing process aimed at sharing knowledge and increasing code quality in your team. In these articles I discussed using the tools already available to you in Visual Studio 2012, like the Unit Test Runner, Code Metrics, and Static Code Analysis.
In this article I want to expand on the tools available by looking at a 3rd party tool called NDepend. So, what is NDepend? First let’s look at the description from their website.
Make your .NET Code Beautiful with NDepend
NDepend is a Visual Studio tool to manage complex .NET code and achieve high Code Quality. With NDepend, software quality can be measured using Code Metrics, visualized using Graphs and Treemaps, and enforced using standard and custom Rules.
Hence the software design becomes concrete, code reviews are effective, large refactoring are easy and evolution is mastered.
Essentially NDepend is an analysis tool that really allows you to dig deep into the structure and quality of your code. You may want to do this for various reasons. You may want to routinely keep an eye on the quality of your project, or you may have to get under the skins of a large piece of legacy code so that you can refactor it.
What you get
Once you decide to try the 14 days license, or have purchased a license you download a very small 10meg zip file from the NDepend website. Once you have un-packed this Zip file you can either run the standalone NDepend analysis tool called VisualNDepend, or run the Visual Studio AddIn installer.
My preferred option is to use the Visual Studio integration. To integrate with visual studio, you need to run the Visual Studio AddIn Tool, as shown below.
Once the installer has finished integrating you can then load up Visual Studio. Once Visual Studio is loaded, load up a solution file. In this article I will run it against my little Safe Pad open source project. To attach NDepend, click on the NDepend menu where you can attach it to the solution file.
Once NDepend has bound to your solution you will notice lots of windows pop up and a report is generated in your browser. On first look this will all feel like information overload. NDepend gives you a lot of detailed information and it will feel very daunting at first.
The main features of NDepend are Code Queries, the Dependency Matrix, the Dependency Graph, Code Metrics and Code Diffs. I will run through each of these below.
NDepend contains a very powerful scripting system called CQLinq. This allows you to write custom queries over your code. For example the script in the image above looks for all types that could have a lower visibility than they currently have. There are around 200 queries and rules provided that you can use, or if you want to invest the time, you can define your own queries. The built in queries though are very comprehensive. What I now try and get into the habit of doing is running the queries and fixing anything that is highlighted in red or yellow. If you feel any of the rules are not relevant to your project, or you disagree with them, then you can disable them as needed.
NDepend outputs various types of visual diagrams to help you see at a glance the overall state of your code. They are great for breaking down a large project into something more visual.
The Dependency Structure Matrix (DSM) is a compact way to represent and navigate across dependencies and coupling between components. A DSM is an alternative to viewing a dependency graph. In fact a DSM is best used alongside a dependency graph. A graph is great if you want to look at dependencies for a small subsection of code and is more intuitive to look at, but they can get unmanageable when analyzing a large code base The DSM lets you observe dependencies of a larger project at a glance all in one view but is not as intuitive. Once you know what you are looking for you can spot structural patterns at a glance.
What I really like about the DSM view in NDepend is that it offers context sensitive help to guide you through what you are seeing. This really helps break down the information presented to you.
NDepend’s DSM relies on a simple 3 colour scheme for DSM cells: Blue, Green and Black. When hovering over a row or a column with the mouse, the Context-Sensitive Help explains the meaning of this colouring scheme.
If a cell in the DSM contains a number, this number represents the level of coupling between objects represented in a row and column. Once you have identified some coupling you wish to investigate further you can use the information in the context help. Also if you click on the cell you will be presented with a dependency graph.
You can tell a lot about the code structure by the sorts of patterns you can see in the DSM view. I won’t cover all these now, but there is a good guide to these on the NDepend site.
If you click on a cell in the DSM you will be presented with a dependency graph showing the coupling identified in that cell. If you look at the example below, you can see there is a cell showing a coupling score of 5 between the RichTextBoxPrinter object and the Formatrange structure.
If you click on that cell, you will see a graph showing the relationship between those objects.
What is really useful is if you right click on one of the objects in the graph you can use the ‘Select Types’, ‘Select Methods’ or ‘Select Fields’ menu to run a code query to highlight all the types that the object uses either directly or indirectly.
Treemap and Code Metrics
In the metric view, the code base is represented through a treemap. Tree mapping is a method for displaying tree-structured data by using nested rectangles. The tree structure used in NDepend represents the usual code hierarchy of .NET Assemblies containing namespaces, namespaces that contain types, and types that contain methods and fields.
You can use the ‘Metric’ drop down box to determine what you want to display. In the example above I have it set to Cyclomatic complexity. The ‘Level’ drop down box is set to Method, which represents the boxes as methods. This can be set to namespace, method, type, field, or assembly.
The purpose of the tree map is to show you methods relative to other methods. The example above shows you the relative cyclomatic complexities. As you can see in the large blue box, there is a method called SetSelectionFontType(). This box very large compared to other boxed. If you hover your mouse over this you can see that is has a score of 25 units. This means that method has a cyclomatic complexity of 25 and is a good candidate for refactoring. If you double click on this box it will take you to the code.
Abstractness vs. Instability
NDepend can produce you a report about your code base (more on this below). One of the charts produced is the Abstractness vs. Instability report.
This chart is very useful for giving you a very high level quality judgement against your software. In its simplest form, if the ‘X’ is in the red, this is bad. If it is in the green, this is good.
The Y-axis shows how abstract your assembly is. In other words can it be extended without recompiling? The X-axis is instability. This doesn’t mean whether your application is instable as about to crash or cause havoc. What this means is that the public interface can’t change because there are lots of assemblies that are dependent on it. Stable means that the public surface area of your assemblies can’t change because there are a lot of assemblies that are dependent on it. An instable assembly has fewer, or no, dependant assemblies upstream.
Here’s how to read the chart:
- If an assembly is very stable (that is, lots of assembles depend on it) and it’s not extensible (no abstract classes, no virtuals, etc) then you’re in the lower-left quadrant of the chart in the Zone of Pain.
- If an assembly is very abstract, very extensible, but no one depends on it (it’s not really being used) then it moves towards the Zone of Uselessness.
Charts like this can give you a lot of insight into how hard it would be to replace a 3rd party component if you needed, or just to extend one.
86 Code Metrics
In my article on ‘Unit Test Coverage, Code Metrics, and Static Code Analysis’ I talked about using Microsofts code metrics to keep an eye on the overall quality of your code. These metrics include Cyclomatic Complexity, Maintainability index, depth of inheritance etc. NDepend provides all these and many more. 82 in fact! You can see a more comprehensive list and description of the metrics here.
When you fire up NDepend, it will generate a convenient HTML report that will pop up in your browser. This report is great as it will run through all the standards metrics, analysis and charts in NDepend and compile them into 1 place for you. This makes it very easy for you to take a quick look into the quality of your code base without having to bury yourself in menus etc. If you do spot issues in the report, you can then refer back to visual studio and dig deeper.
What I also like is that it will run lots of CQL queries and give you instant feedback on the results and highlight if there are any issues.
So, what do I think of NDepend. Well, I think it is a fantastic tool. But I would also say it is equal measures of fantastic and terrifying. The level of information this tool gives you about your codebase is staggering. If you are running a team of developers, I probably wouldn’t give everyone access to NDepend as you could end up in an analysis death spiral instead of hitting your deadlines, but there is definite value in giving it to lead and senior developers who can keep an eye on the overall code quality.
My favourite features are the DSM and how it links into the dependency graph. I also routinely check the CQL code analysis rules on top of the static code analysis rules that I already run.
You can also run NDepend on your build server and have it apply the CQL rules after a build. NDepend is available from their website and costs around $385 for a single developer. If you need more licenses then the price changes on a sliding scale depending on how many seats you require. If you want to run NDepend on a build machine then you need to buy additional licenses for that too.