As I wrote previously I’m a big fan of tools and programs that helps me in my day-to-day work. I also like to test new programs, which is probably the reason that Patrick Smacchia contacted me with a proposition to evaluate his program: NDepend.
In simple words NDepend is a tool that helps improve .Net code quality, by measuring and presenting information about code metrics. It supports C# and Visual Basic languages and integrates nicely with Visual Studio (from 2008 to 2012), providing an easy usage for users.
The list of features that NDepend provides is quite big. From my perspective the most interesting parts are:
- Queries and Rules Explorer/Editor
- Dependency Matrix/Graph
in addition there are also modules for:
- Code comparison
- Test coverage
In this blog post I will focus only on the main functionality.
In our life we can describe objects by simply telling about their properties (like mass, dimension, speed and so on). Using those properties we can compare objects and evaluate which of them is better (for example: which car is faster). In science and engineering we use predefined system of measurement to define item attributes, where every attribute is expressed in its own unit of measure (like kilogram, meter…).
The same approach is introduced in computer science - for the last 30 years, or even more, researchers introduce many metrics that can describe software and code. Those metrics can tell us:
- how hard is to introduce changes
- nesting Depth
- afferent coupling
- efferent coupling
- how large and complex the code is
- number of lines of code
- cyclomatic complexity
- how good the code is documented
- lines of comment
… naming only few from the big list.
NDepend offers 82 most popular code metrics that can be calculated and shown.
Because of hierarchical nature of code elements (fields and methods are in type, type is in namespace, which in in assembly) the metrics are shown using treemapping technique. Depending of selected scope (level) code element is represented by rectangle, which size is determined by the code metric. The rectangle can contain other, smaller rectangles (i.e. namespace has methods). This allows to easily spot problems and patterns. For example if we select a ‘method’ as our scope and ‘Lines of code’ as a metric, the big rectangles will indicate the methods with many lines of code (usually this isn’t good and those methods should be split to smaller ones). The metrics view is one of the most unique and helpful parts of NDepend.
I should mention that some (not many) metrics can’t be calculated and shown for code written in Visual Basic, so if you use VB please be warned.
Queries and Rules Explorer
In essence NDepend provides mechanism for querying your code base for various code metrics and problems that occurs in it. To achieve it, it defines CQLinq (Code Query over LINQ) language, that should be familiar for every .Net developer. For example to find all methods that have more then 30 lines of code we could write such a query:
from m in JustMyCode.Methods where m.NbLinesOfCode > 30
By default NDepend comes with big number of predefine queries which cover such topics as:
- Code quality
- Object oriented design
- Dead code
- Naming conventions
Those queries help spot the places in code that should be improved: methods split into smaller ones, types renamed, complexity reduced and so on. Working with NDepend creates a workflow, where you look for the problem, fix it and then check again if the metrics are improved. After some time your code should be cleaner and easier to maintain.
The nice part about those queries is that you can modify them and even write your own. This gives you full flexibility in adjustment
the tool to your needs.
When the application comes bigger and bigger it is harder to see the big picture of it. We lost idea about dependences in it. The easiest way to see them is to paint a graph, that will reveal all the dependencies. Here comes NDepend, it can create such a graph for us. The graph can have many levels, that shows dependences between assemblies, namespaces, types or even members (methods and fields).
When we work with NDepend, in Visual Studio, we can use it to get various information about the code elements (types, fields, methods, namespaces or assemblies) in the solution. We can query about direct and indirect callers/callees, inheritors, implementers, type usage and so on. All such queries can be shown in a graph, which is nice and helpful addition.
There is only one problem with the graph representation, it becomes blurry, when there is too much objects in it. I had such problem when I used NDepend with large and quite legacy project - the graph was so big that I wasn’t able to read it. I even ask Patrick what should I do, to be able to work with the graph in this project. He pointed me that I should use dependency matrix instead.
As you probably know a graph can be represented as adjacency matrix. This idea was used by NDepend to present a solution dependency graph as a matrix. The main benefit of such representation is that it is more compact and clear to read. This is especially important when you have many assemblies in your solution - in such case graph is too big to be easily read.
At first I didn’t feel comfortable with dependency matrix and it took me a while to be able to read it correctly. The context-sensitive help speeds the process of learning and after few days the matrix was completely natural for me.
There is also one, big, advantage of dependency matrix over the graph. The matrix allows you to spot the structural patterns, which are nice described in the documentation - that I highly recommend you to read.
Visual Studio integration
By default NDepend comes as a standalone application called
Visual NDepend, in addition you can integrate it with Visual Studio. After installing plug-in, you see new menu in the main bar, new context menu in Solution Explorer and few other items here and there. From the menu you have access to all features of NDepend, you can start:
- Class Browser
- Queries and Rule Explorer/Editor
- Dependency Matrix and Graph
- Coverage by Tests
and few others.
To be able to use NDepend in Visual Studio we need to create new project file and add to it all assemblies, that we want to analyze. The project file can be added to the solution file, but this isn’t required. After the analyze is finished the NDepend is ready to go. It is worth mentioning that an HTML report, that summarize all information about your code, is generated after the analyze ends.
The integration is nice and gives impression of well organized. For sure this is very strong point of this tool.
NDepend is very interesting product. It offers wide range of features focused on improving the quality of the code you and your team write.
There is also another, very useful, usage of NDepend that I would like to mention. Sometimes in my work I get a source code from completely unknown project and I need to estimate how much work is to introduce changes to it. In such case I start NDepend, run queries and look at the metrics - if those aren’t bad I can assume that changing this code won’t be so hard. Of course this isn’t always true, but if you need to do the time estimation, everything can be helpful.
Note: I’ve used source code from Nancy project in the presented screenshots