Static analysis tools allow us to measure code quality and better understand the design and architecture of software. There are things about source code that are not visible to eye in our day-to-day work: dependencies between components, cyclomatic complexity of methods, hidden and indirect dependencies. There are dangers that a method or a type will become overly complex and induce maintenance nightmare without us even noticing it.
Today’s post is about NDepend, a static analysis tool developed by Patrick Smacchia. NDepend measures software quality by extracting metrics, gathering and reporting statistics and visualizing architecture.
Here’s what NDepend does:
- It analyzes .NET assemblies and provides all thinkable information about them both in a report and interactively
- It reports various metrics about assemblies, namespaces, types and members
- It treats the source code as a database and provides a powerful Code Querying Language (CQL) that allows you to write custom SQL-like queries against your codebase
- It allows navigating the codebase using links, references, usage graphs, call graphs, etc.
- Unlike some other static analysis tools, NDepend provides rich interactive visualizations of your architecture, that allow you to visually understand layering, distribution of code, code sizes, relationships and dependencies
- NDepend has an extensive set of Queries and Constraints (compare with FxCop rules) that run against compiled binaries and provide suggestions on how to improve your code (“Top 10 complex methods that need refactoring”, “All methods that shouldn’t be public and can be made internal”, etc.)
- You can run all these queries to get a full analysis report about your software
Since both Patrick and I like static analysis and are interested in measuring software quality, Patrick suggested that I try out NDepend on one of my projects and share my experiences – and I gladly agreed. I’ve heard about NDepend long ago, and even before I joined Microsoft I blogged about static analysis tools and publicly promised to take a look at NDepend someday, which I felt was a very interesting tool with unique capabilities. Well, since Patrick recently contacted me himself :), there can be no better opportunity to download NDepend and give it a try. Here I’ll provide my first impressions.
I went to www.ndepend.com and started to look around. I liked the site and the fact that there were screenshots and some nice 3-min overview videos. Seconds after clicking on a big download button, NDepend was on my desktop. It comes with two executables – command line NDepend.Console.exe (for the build automation) and the UI VisualNDepend.exe. Of course, I started the VisualNDepend first and it presented me with a nice start page:
The next thing is to create a new NDepend project and add the assemblies to it that you want to analyze.
- First thing that you have to do is to create a project and add the .dlls. Make sure the .pdb files are next to it, so that NDepend can locate the source files and provide additional goodness. If .pdb files point to a non-existing source location, you can use the source file rebasing feature in Project Properties -> Analysis.
- I loaded my 6-assembly StructuredEditor project and it automatically displayed the dependent .NET framework .dlls:
- The next step was easy to find as well: the Big Green Run Button to start the analysis:
After the analysis ran, it displayed a very comprehensive report about my project. Even glancing over this report already provided a lot of useful information to me:
- I was pleased to see that my overall code quality is pretty good 🙂
- It was good to know some quick metrics (number of lines of code, comments, IL instructions, assemblies, types, abstract classed, interfaces, value types, exception classes, attribute classes, delegate classes, percentage of public types and methods, etc.)
- It provided a nice visual view of all assemblies, types and members sorted by code size:
- I was pleased to see my code in the green area of Abstractness vs. Instability (green is good!):
- NDepend visualized the assembly reference graph for me:
This is really great, since I had this graph in mind before, but I never saw a tool draw this graph for me automatically – it’s like it was reading the architecture from my thoughts.
- Finally, it provided a long list of CQL Queries and Constraints (you have to see for yourself, I won’t post it here)
- Just reading the rules can be as useful as reading Framework Design Guidelines. Just for example, I learned this:
// <Name>Attribute classes should be sealed</Name>
WARN IF Count > 0 IN SELECT TYPES WHERE IsAttributeClass
AND !IsSealed AND !IsAbstract AND IsPublic AND !IsInFrameworkAssembly
// The .NET Framework class library provides methods for retrieving custom attributes.
// By default, these methods search the attribute inheritance hierarchy; for example
// System.Attribute.GetCustomAttribute searches for the specified attribute type, or
// any attribute type that extends the specified attribute type. Sealing the attribute
// eliminates the search through the inheritance hierarchy, and can improve performance.
After examining the report, I came back to the main application to find that it presents all the information contained in the report, but interactive:
I have to say that the UI looks great, but at first seems rather overwhelming and I felt like sitting in a Boeing cockpit. But hey – you can’t expect a complex static analysis tool to have a notepad-like interface – it has to expose its features somehow. Surprisingly, you get used to the UI really quickly and I found my way around really easily.
All you have are the following things:
- Class Browser – displays all assemblies, namespaces, types and members
- Metrics – displays a visual map on various levels (types, members, namespaces, etc)
- Dependency matrix – helps you analyze dependencies between two code elements
- Dependency graph – draws a DAG (remember I was writing about DAG and Topological Sorting?)
- CQL Queries – a library of predefined queries over your codebase (and you can write your own!)
- Info – information about the selection (updated with focus changes)
Hopefully this can provide a basic overview of NDepend, what it’s for and what it does, as well as its main features. I was very impressed with the tool, really liked it and looking forward to use it more for better architectural insights and better code quality.