Getting started with NDepend

So, after quite some time, I have finally got my thumb out and added an NDepend project to my new .NET Extensions 2.0 solution, in order to get some analyzing done before releasing it.

The first thing that hit me was how easy it was to attach a new NDepend project to my solution. I just had to:

  1. Install Visual NDepend
  2. Open my .NET Extensions solution
  3. Under the new “NDepend” main menu item, select “Attach new NDepend project to solution”
  4. Select all projects of interested (I chose all of them)
  5. Press the OK button and pray to god.

Once NDepend is attached to your solution, the menu will change and look like this:

The NDepend menu

The NDepend menu

…but before that, it will perform a first-time analysis of all projects that it is set to handle. This is done automatically, so just bind NDepend to your solution, and it will perform the analysis…

…after which Firefox (or, naturally, your default browser of choice) will come to life and display a complete analysis summary, which is generated in a folder called NDependOut:

The generated NDependOut folder

The generated NDependOut folder

 

So, what the report has to say?

Report sections

The report is divided into certain sections, of which more (to me) are more interesing than others.

The various sections of the NDepend report

The various sections of the NDepend report

 

Application metrics

Well…first of all, a complete textual summary of application metrics is presented:

The NDepend Application Metrics summary

The NDepend Application Metrics summary

 

Now, this summary contains a couple of interesting metrics.

Note, for instance, the comment ratio (51%). I have always taken pride in commenting my code, but lately, I have focused on writing readable code instead πŸ™‚Β  However, I have decided to overdo the commenting in this project, since it must be understandable for users that only get their hands on the DLL.

Since .NET Extensions is mainly an extension project, I think that this summary is quite what I expected…even if I maybe could do with a bit more interfaces. Note that not much is going un “under the hood” – almost everything is public (in some cases for unit test purposes, which I will change #beginner-error).

Also, since I am of the belief that one should NEVER work directly towards an object’s fields, I am happy that I have no public fields at allΒ  πŸ™‚

The last row (cut of) displays the method/function with the worst cyclomatic complexity:

The worst CC in the solution

The worst CC in the solution

However, when I analyze the method with the Visual Studio analyzer, it says that the method has a CC of 13! Turns out that 25 is the ILCC (Intermediate Language Code Complexity) – the resulting CC. However, I will write a new blog post later on, in which I’ll use this information to improve the GetHtml() method. Stay tuned πŸ™‚

 

Assembly metrics + abstraction/stability summary

After the interesting application metrics summary come some assembly metrics (also quite interesting) as well as information about for the stability of the different assemblies.

First of all, everything is presented a textual grid:

The NDepend Assembly metrics table

The NDepend Assembly metrics table

This information is then displayed in various graphical components, such as the Visual NDepend view (in Visual Studio, you can use NDepend to navigate through this view)…

The Visual NDepend View

The Visual NDepend View

…as well as the Abstractness vs. Instability view…

The Abstractness vs. Instability view

The Abstractness vs. Instability view

 

Now, let’s stop for a moment and discuss this graph. The word “instability” first made me feel like I had written the worst piece of junk there is, but I think that the word is quite misleading.

As I’ve mentioned, the analyzed solution consists of a lot of extension and helper classes, which almost never are independent – they mostly depend on other base classes, since that is their purpose. If I have understood the term “instability” correctly, this is exactly what it means. The solution is instable since it depends on a lot of other components…

…but for this kind of solution, it is hard to have it any other way. After reflecting over the graph a bit, and enjoying the green color (except for the so far empty build project), I understood what view intends to display.

 

Dependencies, build order etc.

This part of the report is probably a lot more interesting if you intend to delve into a solution of which development you have not been a part of earlier on.

However, for this particular situation, this part of the report really did not give me anything that I did not already know.

 

Amazing final part – constraints

Finally, NDepend displayes an amazing part where the code is evaluated according to all existing constraints.

For instance…

 

One of the vast number of constraint summaries

One of the vast number of constraint summaries

 

…this part displays a constraint that selects all functions that:

  • Has more than 30 lines of code OR
  • Has more than 200 IL instructions OR
  • Has a cyclomatic complexity over 20 OR
  • Has an IL cyclomatic complexity over 50 OR
  • Has an IL nesting depth that is larger than 4 OR
  • Has more than 5 parameters OR
  • Has more than 8 variables OR
  • Has more than 6 overloads

For instance, the first item in the list – Split() – is there because it has more than8 variables.

Some of the default constraints are perhaps a bit harse, but most of them are really useful. Just having a look at these constraints and at how your code applies to them gives you a deeper understanding of how you (or your team) writes code.

 

Type metrics

Finally, comes an exhausting, thorough grid with ALL the information you can imagine about every single type in the solution.

Type metrics

Type metrics

The “worst” cells in each category are highlighted, which makes it really easy to get an overview of the entire framework…although the information is quite massive.

 

Conclusion

Well, only having connected an NDepend project to my solution, I have barely scratched the surface of what NDepend can offer. To be able to extract this much info by just pressing a button, is quite impressive.

I wrote this blog post yesterday, and have rewritten large parts of it today. During that time span, my stance towards it has shifted a bit.

Yesterday, since I then did not understand parts of the report, I was under the impression that your own hobby project is not the best context in which to use NDepend…and that it comes to better use when working in a role (e.g. tech lead / lead developer) that require you be able to quickly extract data about the systems for which you are responsible. In such a context, NDepend is greaaat.

However, after getting some time to “feel” how NDepend “feels” for me as a developer, I have started to see benefits even for a solution such as this extensions solution. As I will show in a future blog post, I can use the information I extract from NDepend to detect the parts of my framework that are “worst”…and makes it easy to adjust them, re-analyze them and see how my implementation grows better.

It is a bit like comparing my iPhone with my iPad. ReSharper was like my phone – as soon as I started using it, I could not live without it. NDepend, on the other hand, is much like the iPad. At first, I really could not see the use, but after som time, it finds right into your day-to-day life and…after a while…becomes natural.

I will scratch myself further down into NDepend. Stay tunes.

Advertisements