.NET Backend Tools

NDepend – a powerful code analysis tool

Writing software often happens to a situation in which we come to the question „What am I actually reading?”. There are several reasons: the  code can simply be bad-written and not readable, we expand methods and classes, along with the implementation of new functionalities of the system or we create „temporary” solutions , which usually turn out to be those final. The whole can further enhance teamwork, where the risk of any of the described symptoms is growing very strongly. Does this mean that we are doomed to constantly monitor all our applications and find errors or omissions? Not completely. We can help us, using a dedicated tool. One of them is NDepend. I’ve heard about it a few times, and I knew that it is a solid product, perhaps because it uses none other than Scott Hanselman. By chance, I recently received a license of the tool, and thus I have the opportunity to present to you its features.

 

Getting Started with NDepend

NDepend is a paid tool, but producers offer us a free 14-day trial version. Here’s the link. The entire installation is reduced practically to unpack the received zip file. At this point, it should be noted that the tool can be used in two ways: as a window application, or as the addition to Visual Studio, which is compatible with version 2015 to 2010 inclusive. Today, we focus only on the first method. At first, we will see the view very similar to VS which at once is persuading us to conduct analysis of our code:

 

sample1

 

Next, we are proceeding to choose the solution, which we want to analyze.  A nice addition is auto-detect of all the * .sln files on the computer, so we do not have to dig through a pile of folders. A happy little thing. After selecting a project, we go to the selection of assembly, that we want to analyze. In our example, we select all the * .dll files:

 

sample2

 

When all the files are selected, we can begin the analysis. In this window, it is worth to pay attention to the little checkbox that is located under the button. When selected, all results will be exported to the HTML file, and they will appear in the form of a report in our browser.

 

Results visualization

When code testing is complete, we can proceed to analyze the results. NDepend provides some simple views that allow us to quickly assess the status of our application. The first of these is the dependency graph that looks like this:

 

sample3

 

Its purpose is to illustrate the dependencies in our system of external libraries (beige?) as well as those written by us (gray). As a result, we are able to monitor our entire application (or part thereof), and quickly respond to any irregularities, whereas normally we would be forced to read all „using lines” in our code. If you need more detailed analysis of a bubble, just click on it and then select „View Internal Dependencies on Graph”. Example for CQRS.Domain:

 

sample4

 

It is also worth mentioning that the size bubbles and thickness of the arrows are not accidental. The default dependency for the size of the bubble is the amount of code, and the thickness of the arrows determines the number of types used from the library. However, you can change these criteria, e.g., The number of IL instructions or the number of methods used from a specific library.  If this form of the diagram does not fit you, you can choose an alternative in the form of a matrix. It looks like this:

 

sample6

 

Here we can also go down a little bit deeper. For instance by clicking on one these small squares we will see:
sample7

 

We know e.g. that the EventBus class has a dependence on the IEventHandler interface <TEvent>. Let us go farther. The next view looks as follows:

 

sample5

 

In the default mode, it shows us the complexity of our code, expressed in lines of code, where each box is one method. Note the slider on the right side of the diagram, by which we can quickly change tolerances. As shown in the example, not everything looks beautiful. At first, I was a bit disappointed by this fact, but after a moment of analysis, it turned out that the methods marked in yellow and red are the default MVC method generated by VS. Whew 🙂 I will only admit that here also we have the ability to change a set of visualized data.

 

 

Code Queries/Rules

For me, it’s the coolest feature. So what is it? When we look at the interface of the tool we see two small windows at the bottom:

 

sample8

 

In the left window, you can see a group of declared rules that our software should meet to be cool. Exemplary groups are

  • Code Quality
  • Object Oriented Design
  • API Breaking Changes
  • Dead Code

 

The right window shows specific rules within the selected group. Example for Quality Code:

  • Methods too complex
  • Methods too big
  • Methods with too many variables
  • Types with too many fields

 

Each rule apart from the name has a graphics which is illustrating whether our software is meeting given requirements. If everything is all right, a green dot will appear. Otherwise, we will see the warning symbol along with the number of elements which should be checked. Additionally, the yellow icon can additionally be provided with the red element which will inform us about the breaking the critical rule of our software. After clicking on the selected rule to the left, we will see the tree so that we can immediately go to the VS to correct. An example for the „Methods too big” rule:

 

sample9

 

As you can see the GetOrCreateModelDescription method does not meet the expectations of NDepend. What is important is the query that has been generated in the window above. This is called Code Query which easily (and more importantly in real time) allows us to write LINQ queries that will return method, class or field according to our criteria. In addition, our query, we can bear the warnif clause, which causes that the group will be visible only after exceeding a specified threshold of tolerance. Here are a few random Code Queries:

 


//methods too complex

warnif count > 0 from m in JustMyCode.Methods where
  m.CyclomaticComplexity > 20 ||
  m.ILCyclomaticComplexity > 40 ||
  m.ILNestingDepth > 4
  orderby m.CyclomaticComplexity descending,
          m.ILCyclomaticComplexity descending,
          m.ILNestingDepth descending
select new { m, m.CyclomaticComplexity, 
                m.ILCyclomaticComplexity,
                m.ILNestingDepth  }
-------------------------------------------------------------
//Class with no descendant should be sealed if possible
warnif count > 0 from t in JustMyCode.Types where 
  t.IsClass && 
  t.NbChildren == 0 && 
 !t.IsSealed && 
 !t.IsStatic 
orderby t.NbLinesOfCode descending
select new { t, t.NbLinesOfCode }
-----------------------------------------------------------
//Avoid the Singleton pattern
warnif count > 0
from t in Application.Types
where !t.IsStatic && !t.IsAbstract && (t.IsClass || t.IsStructure)
where t.Constructors.Where(ctor => !ctor.IsPrivate).Count() == 0
let staticFieldInstances = t.StaticFields.WithFieldType(t)
where staticFieldInstances.Count() == 1
select new { t, staticFieldInstance = staticFieldInstances.First() }

 

So you can see that in a relatively simple way we can freely create our rules, the correctness of which we can quickly and accurately enforce in the future.

 

Code diff

The last thing I wanted to mention today is the ability to compare different versions of the code. So this is a good option when working in a team. To start the analysis, in the top toolbar, go to the:

 

DIFF -> Define Two Snapshots to Diff -> Choose Assemblies or Analysis Results to Compare

 

Then in the dialog box, we can select the snapshot to compare, or * .dll files:

 

sample10

 

We are interested in the second option, therefore we are dragging *. dll files from two different buildów. After a moment our result looks as follows:

 

sample11

 

Thus we see that one of the methods increased by 4 additional lines. What is important in all this is the fact that our Code Queries record the differences between the two builds. Therefore, if one of the programmers suffer too much flow and spoil our quality of our code (eg write too long method), we will be able to quickly detect that and react.

Summary

I encourage you to get acquainted with the trial version of NDepend. What I’ve shown was just the tip of the iceberg. I am leaving the conclusive assessment to you 🙂 If you don’t want to miss my future posts, I encourage you to follow me on Twitter  or leave a like on my Facebook fan page 🙂