Recently I’d had the opportunity to begin exploring code through the eyes of NDepend. I’ve pointed NDepend at my code, open source projects, code at work, just about anything I’ve had the time to load into Visual Studio. Has it been a useful experience? I’d have to say at this point, yes. I’d like to now present a roundup of the features that I’ve enjoyed the most.
What is NDepend
NDepend is a tool that simplifies managing a complex .NET code base. Architects and developers can analyze code structure, specify design rules, plan massive refactoring, do effective code reviews and master evolution by comparing different versions of the code. (ndepend.com)
NDepend, in my opinion is fairly complex, and there seems to be a fair depth to the number of features that you’ll discover as you continue using it, however, here are the features I found initially to be the most useful.
- The predefined CQL Queries
- Query results
- Metrics window
I think the predefined CQL queries window really is the quick way to get up and running in learning about your code. There a dozens of queries ranging from design issues, naming issues, boxing, complex code to just name a few. Not only that, it’s really easy to actually get in there and customise the query to suit what you’re looking for.
The first feature I was able to use here was to generate and export a report of potentially unused methods. Most codebases seem to somehow accumulate orphan code that can be removed, however its probably hard to find easily without such tools.
The query I have running in the window below was helping diagnose the portion of the codebase still depending on Hashtables and ArrayLists. The very cool thing I noticed here was that NDepend won’t just tell you the underlying classes that contain these lists, it will shade in on the metric view ALL code effected by it. Even if the lists are wrapped and used elsewhere much higher up.
Related to the CQL, the Query Results window is one that I really wish was a dockable panel inside Visual Studio. By clicking on any member displayed here NDepend will just to the corresponding line of code. Very simple and easy to explore.
The Metrics view was useful to provide an at a glance distribution of the current code query. It can also show the members that have changed when comparing multiple versions of an assembly. One of the projects I tried was a change comparison between DNN4.9.2 to 5 However, although the core libraries had significant change it did not drastically effect many of the public interfaces.
Visual Studio Integration
The plug-in for visual studio provides a large array of quick queries and lookups, I like to think of it as ‘Find all References’ on steroids because it gives so many more options and so much 'deeper' information. This starts to relate to things such as Efferent and Afferent coupling, knowing about these factors may definitely assist you when it comes to making refactoring decisions.
Code comparison of a slightly core modified version of DotNetNuke 4.9.1 to 5
# IL instructions 229 806 to 268 470 (+38 664 +16.8%)
# Assemblies 11
# Namespaces 95 to 110 (+15 +15.8%)
# Types 725 to 830 (+105 +14.5%)
# Methods 9 165 to 10 813 (+1 648 +18%)
# Fields 2 954 to 3 362 (+408 +13.8%)
Tier code used by the application:
# Tier Assemblies used 12
# Namespaces used 68 to 67 (-1 -1.5%)
# Types used 565 to 573 (+8 +1.4%)
# Methods used 1 671 to 1 750 (+79 +4.7%)
# Fields used 64
Viewing NDepend’s class browser in Code Comparison mode guides you through what’s changed. Everything from changes in the number of lines of IL, public methods, fields, namespaces, assemblies to test coverage. It may be nice to have these stats, however well structured release notes will do me much better than telling my a library has grown by 33%. I think the more important factor here is capturing changes to public interfaces and also test coverage %.
Getting to know your code…or someone elses
When you first come across a new codebase and start to familiarise yourself there are always a number of things that you may want to look at including
- What are the most important namespaces, classes and methods; NDepend provides this this by a simple lookup then displays it visually. You can also make use of the ‘MethodRank’ feature to find the most used methods.
- What are the classes with the highest coupling, not necessarily the most important classes. These are the ones to watch out for as they may be the ones doing ‘too much’. Kind of along the lines of the Single Responsibility Principle and even Separation of concerns.
I think in terms of ‘what’ NDepend does, all the information is there ready to be accessed, however there are a few suggestions I’d really love to see that would make having the data a little more ‘at your fingertips’.
More Visual Studio Integration, there are already some useful integration menus but I see a lot more potential for the information that NDepend can provide. If I had one feature request, it’d be to have that Query Results window as a Visual Studio dockable panel. The idea of not having to keep switching away from VS while I explore the results would be a good thing.
Although NDepend mostly has this covered, back in 2006 when I was trialing Parasoft’s .TEST one of the really handy concepts was to present you with 10 issues that you should fix today. So the idea of helping to progressively improve your codebase.
Shout-out to Patrick Smacchia for giving me the opportunity to test drive NDepend.
I think I’ll continue to use NDepend going forward to see what else I am able to discover, and perhaps write a more advanced post. For now, I think it has shown that there are enough easy to use feature in there that even new uses can obtain some immediate value.