NDepend - My Experience
NDepend - My experiences
I recently started playing around with NDepend. Primarily I have been using NDepend to analyse NinjaNye.SearchExtensions.
First impressions
NDepend is hugely in-depth. My first analysis returned so much information it was difficult to know where to start. Fortunately, NDepend gives you a handy interactive dashboard that summarizes the results and allows you to drill down to the specific rule violations you are interested in.
UI
This product is vast. The sheer number of metrics means you can easily get lost. However, the UI (and VisualNDepend in particular) helps to resolve this by allowing you to quickly and easily navigate to any depth in the metrics.
Once you have completed analysis you are given a html report as well as a Dashboard that summarises key points. Other useful interactive tools to utilise are the Dependancy Graph and an the interactive Metric Map.
Personally, I prefer to run and analyse my metrics in VisualNDepend. The differences between this UI and using the VS integrated view are small, however VisualNDepend is built specifically for this purpose and doesn't have to compete with all my code windows in VisualStudio which means everything just seems to flow a bit easier.
The Dashboard
The first thing that jumped out at me were the 2 critical rules that had been violated. The two rules I was breaking were as follows:
- Avoid namespaces mutually dependant (1 occurence)
- Potentially dead methods (8 occurences)
The first thing I thought I'd tackle was the 8 potentially dead methods. Fortunately, the methods it had identified were solely used when building Expression Trees so none of these were valid. I was able to easily remove this rule from my reporting but that does mean I would not have this rule appear if I genuinely violated the rule.
The 'Mutually Dependant Namespace' violation the second critical violation and was something that was valid. Now that I was aware of this I was able to make a few changes to the code structure and resolve the issue.
##Performance There are some methods in SearchExtensions where performance is important, namely the Soundex and Levenshtein functionality. I was able to leverage the stats from NDepend to try and reduce the amount of IL Instructions and therefore improve the performance.
My LevenshteinProcessor
for example, had a total of 257 IL instructions which I was able to reduce to 218 instructions (a 15% reduction). This was a concrete measurable way of reducing IL instructions which in turn should have a positive affect affect on performance and something I would not have reliably been able to do without NDepend.
Warnings
Whilst analysing my code I did notice that some of my code returned warnings that, it could be argued, were not issues at all. One instance of this was Potentially Dead Methods. Dead methods were in fact used but through expression trees so the code was not aware that they were being used. In fairness to NDepend, the warning is prefixed with 'Potentially' and NDepend provide a really easy way of informing the analyser to ignore a method. You simply need to create an attribute and alter the rule definition as follows
// If you don't want to link NDepend.API.dll,
// you can use your own IsNotDeadCodeAttribute and adapt this rule.
!m.HasAttribute("NinjaNye.SearchExtensions.NDepend.Attributes.IsNotDeadCodeAttribute".AllowNoMatch()))
Another warning that came up related to some Entity Framework Code First code. The critical rule that had been violated was the 'Method with too many parameters' rule. The feedback was that I had a bunch of methods with up to 15 parameters...??? (WHAT!!! Had I really done that...?). After some investigation looking into this I realised that the code at the source of this violation was Entity Frmaework configuration code that creates tables from my model classes, similar to the following:
CreateTable(
"dbo.Table1",
c => new
{
Id = c.Int(nullable: false, identity: true),
CompetitionId = c.Int(nullable: false),
WeekId = c.Int(nullable: false),
StartDate = c.DateTime(nullable: false),
...
...
})
This was slightly annoying something I would like to see if I could avoid by editing the rule, however at first glance, I could not see an obvious way of ignoring anonymous methods. (Please get in touch if you have done this)
Summary
I have been using NDepend for a couple of weeks now and I feel I am still only scratching the surface on what it can offer. The stats NDepend provide are so vast I have yet to master all but a few metrics. The metrics I have used have been incredibly useful in identifying code to refactor.
NDepend is also incredibly flexible and allows you to customise which rules to use as well as the definition of each rule meaning you can tighten or relax the definition of a rule to suit your needs.
If you would like to share your opinion, please use the comments form below. Alternatively, if you would prefer, feel free to get in touch with me via twitter @ninjanye