Welcome a new member in my toolbox: NDepend. If you haven’t seen it yet: it is a tool for static code analysis for .NET code – static code analysis meaning that it looks at a set of assemblies and source code and tries to figure out how it all hangs together, and tells you something about its inner characteristics. It can for example tell you which are the most referenced or the most complex classes in your project, and if the way that your project is really structured is similar to the way you think it is. NDepend also sports the most busy, dense, chaotic and against-any-expectation user interface that I have ever seen, and you too.
I have been using NDepend once in a while for some while, but more on an on and off basis. I basically used it as a means of due diligence on code that I do not know, but have to get my feet into. NDepend can give you an overview of the structure of a large piece of software, and some of its problems, in 15 minutes. Now, I found a reason to use it on an at least weekly basis.
I’m currently involved in a project where multiple SCRUM teams are working on the same code base. When a Sprint (that is a project step in a time box of four weeks, but you should really know that) ends, the team runs a demo with the product owner (“PO”), who decides if the result are acceptable. Each Sprint is on its own code line. Now after the PO gives her OK, the code can go to the MAIN code line: the content of the product that is going out to the customer (it’s not that simple, but you get the picture).
Now the PO does not really care about code quality, unit test coverage and quality, or the completeness of test plans. So before the code that comes out of a Sprint is released to MAIN, it is reviewed by an independent group of developers, and this is where I’m involved. Not all code from the Sprint is reviewed, about 10% are normally sufficient to see if a team has put enough emphasis on clean and structured work. But how do you find out what has been changed, and how do you pick the 10% that are most relevant?
The approach until now is to get the list of changed files from the source control system, and pick the files to review by making a guess. The problem is that the list of changed files does not tell you how much has changed – often, there has been just an adjustment in the code formatting or the correction of a typo that caused the checkin.
And this is where NDepend is hugely helpful. It can not only run an analysis on a single project, it can get you the difference between two analysis results. In order to determine what has changed in the Sprint, you run an analysis on the state of the MAIN code line, and take that as the baseline for a differential analysis of the Sprint code line. What you get immediately is a ranking of types and methods that have been added or changed, in the order of the magnitude of the change, across multiple assemblies. That alone make a huge difference in the quality of the code review, and the time you need to get there.
And that is only the start. The most powerful feature of NDepend is that you can run queries in a SQL-style lingo against the code analysis. This for example creates a warning when you’ve got methods with too many (logical) lines of code:
WARN IF Count > 0 IN SELECT TOP 10 METHODS WHERE NbLinesOfCode > 30 ORDER BY NbLinesOfCode DESC
NDepend comes with a good set of these predefined queries, and you can write your own. Let’s say we want to get the classes with little comments, but only in code that has been added or modified within the Sprint:
SELECT TOP 50 METHODS WHERE (WasAdded OR CommentsWereChanged ) // Only modified and new AND ( NbLinesOfCode > 20 // A lot of code OR CyclomaticComplexity > 15 // A lot of paths OR NbVariables > 8 // Many variables ) AND !IsGeneratedByCompiler // Exclude anonymous types ORDER BY NbLinesOfCode DESC
In addition, you can actively search for things that you do not wish to see, like
- References to MVVM ViewModels
- References on concrete classes rather than on interfaces
- FxCop suppression attributes
- Usage of NotImplementedException
- Low unit test coverage
The only real limitation I’ve ssen is that a query can either run against types, methods, namespaces, or fields, but not against a mixture. You can for example not search for property setters that do not use the PropertyChanged event in types that implement INotifyPropertyChanged.
NDepend is free for limited usage for evaluation, academic, and open source projects; for commercial projects or the full feature set you’ll have to buy reasonably priced licenses.
Oh yes, and: NDepend can be targeted at Silverlight 3 and Silverlight 4 as well as normal .NET code.