Jul 28 2008
Evaluating NDepend
I played with NDepend over the last two months and it turned out to be quite a useful tool. NDepend performs all sorts of static analysis on .NET code and evaluates code quality and complexity. The thing that makes it stand out from the rest of static analysis tools is, at least for me, the fact that it stores results into a form that can be easily queried to implement custom code quality metrics and restrictions.
NDepend makes it easy to identify dead code (not used from anywhere) or hot-spots that are shared across a lot of the system, methods that are too big or complex and classes with too many methods or elements. NDepend’s CQL (code query language) gives me easy access to the analytics results which would theoretically enable me to finally break the build if someone starts adding implementation specific references to core interfaces or something similar. In practice, I’ve been playing with NDepend for over a month and I’ve been too lazy to look into this, so that will probably never happen. In any case, if you are less lazy than I am, the CQL query editor looks fairly simple and the language seems similar to SQL, so implementing any sort of code statistic verification should be easy. NDepend has a GUI frontend (Visual NDepend) and a command line tool that can easily be integrated with CI systems.
A very nice feature of NDepend is running cohesion and coupling statistics on assemblies. On the very top of the report, you’ll see scores for two types of coupling (Afferent and Efferent) and internal cohesion. Afferent coupling is a measure of how much the rest of the system depends on an assembly and Efferent coupling measures how much an assembly depends on the rest of the system. NDepend also gives its marks on stability and abstractness of the assemblies, so you can quickly check whether the reality matches the intention.
NDepend also produces several visualizations of the project. The famous proverb says that “A picture is worth a thousand words”, and NDepend attempts to achieve that effect with the diagram charting assemblies between the zones of pain and uselessness based on abstractness and instability. Here is the picture for my favourite opensource .NET project (click on the image for a larger version).
Another visual view of the system is the block area of assemblies, with each assembly taking up the space according to its size, nesting depth, number of methods or some other statistic. Having a visual overview of these statistics is certainly interesting, but I think that the current way of displaying the data is not really useful. Again, here is the picture for my favourite opensource .NET project. In my opinion, a classic colour-coded pie-chart would do a much better job. Surface-area mapping is not really readable, especially with assembly names broken into multiple lines to fit into the area.
The third visual display, showing assembly dependencies, was the most interesting one for me, probably because that concerns me the most at the moment. Having a quick visual overview of module dependencies would be very useful. Unfortunately, this only works with a small number of assemblies. On more complicated projects, the diagram is relatively useless, because it just looks like a spider’s web. You can see an example on the right (click on the image for a larger version). I think that this picture would be much more useful with a different positioning algorithm, that would make it easier to follow connection lines.
NDepend costs between 180 and 300 Euros per license, so it is not at all cheap. Does it have enough functionality to justify the price? If you are working with a large code base, definitely. On smaller projects, probably not. I already got one of the companies that I am consulting at the moment to license it and put it on the build server. At the moment, it just runs standard reports but I hope that we’ll have time to add some quality controls soon and break the build when someone has been naughtier that usual. I’d definitely love to see the readability of visual reports improve in the future.
![]() |
![]() |




