Tag Archives: NDepend

NDepend v2017

With NDepend v2017 being released recently, I thought I had to give it a test drive. Whilst I’m not an architect, sometimes I have to do a bit of architecture. Especially with home projects. It’s not like I can call Architects-R-Us and have them send an Architect around to produce an architecture for every app idea I have. And so I have a slowly growing interest in this space. This time I thought I’d write more of a tutorial about how to get going with NDepend.

Once you’ve downloaded NDepend and got the exe on your hard drive, you fire it up and point it at the sln file for a Visual Studio solution which you want to profile. It will pick up the projects in your solution and the dialog will look a little like this:

Figure 1 – Analyze Assemblies dialog

Click the Analyse 10 .NET Assemblies button and NDepend will perform its analysis and come back with another dialog:

Figure 2 – Analysis Complete dialog

The other thing it did was to launch an html NDepend Report Summary, because I had the Build Report checkbox ticked in the first dialog. More on that report summary later. So I clicked on the Show NDepend Interactive Graph button:

Figure 3 – Assemblies Graph

A dependency graph is displayed and it is interactive! I clicked on the UI node (far left) and it lit up the map with the dependant assemblies. More importantly, it showed a couple of windows which are yellow in colour and positioned at the left and foot of the screen. The window at the foot has help topics relevant to the current context. The window on the left is the most interesting. It is scoped to the selected graph node and provides a heap of at-a-glance information about that graph node and its descendants. Lets try again and click a node lower in the graph.

Figure 4 – Assemblies Graph with Descendant Selected

Figure 5 – The Dashboard

You can see that the ancestor nodes in the graph are green and the descendant nodes are blue. And again, the pop-up dialog (this time on the right) contains information scoped to the selected graph node (in this case, HomeLibrary.UiModel, a project which contains my DTOs): Despite a couple of issues in the code, I’m happy with the information which this graph is telling me. The dependencies are pretty much what I intended and I’m getting a good 50,000ft view of that. So lets poke around a bit more. I’ll click on the Dashboard tab a the foot of the main pane. This shows me a plethora of information and the thing I really like about it is the use of colour. Red – bad. Yellow – warn. Green – pass. At a glance, I can get a feel for the health of the application.

Figure 6 – Quality Gates

Figure 7 – Rule Violation

I can see I have 2 Quality Gate fails. That basically means I cannot release my application. Not until that number goes down to 0. Lucky this is just a sample application. So, lets take a look at what I need to fix! After clicking on the little red “2” link, I found that 1 of the 2 quality gates was a collection of 6 rules which I had transgressed:
There was one which immediately interested me, so I investigated further. It was called Attribute class name should be suffixed with ‘Attribute’. Absolutly! That would not like me to do otherwise. So, I double-clicked that rule to discover the culprit:

Looks like NoReorder was a class that was generated by JetBrains (probably Resharper). Being a generated class, I feel like I’m cool with this. And so here is where things get interesting. I’m going to try something here. If you look at the image immediately above, you can see some text which looks like a LINQ query. That’s called CQLinq and is what NDepend uses to return the results which show whether rules have been violated or not. As an extensibilty point, NDepend allows you to modify these queries and save them. And it saves them for this project. So, I made a quick and small modification to the query, taking advantage of the intellisense which is available in that context:

{
	// <Name>Attribute class name should be suffixed with 'Attribute'</Name>
	warnif count > 0 from t in Application.Types where 
	   t.IsAttributeClass && 
	  !t.NameLike (@"Attribute$") &&
	  t.FullName != "KesselRun.HomeLibrary.UiModel.Annotations.NoReorder"
	select new {
	   t,
	   Debt = 5.ToMinutes().ToDebt(),
	   Severity = Severity.Major
	}
}

I added the line of code t.FullName != "KesselRun.HomeLibrary.UiModel.Annotations.NoReorder". When I saved the query, that rule was no longer violated. I’m not sure if that is NDepend’s recommended way for handling that, but it is pretty cool that you can have such fine-grained control.

Moving on from Quality Gates, I want to take a look at a new Feature in NDepend 2017 called Technical Debt. They’ve taken this well-known concept and applied it in an innovative way into NDepend. You can see from the Dashboard screenshot above a section called Debt. Scoped to the overall solution, my app is receiving a B. But you can also see how this value changes depending on where your context is scoped to. If you take a look at the 2 dependency graph screenshot above which have the yellow information windows, you would have noticed a Debt Rating item. And it is scoped to whatever I have clicked. So what is this?

In a nutshell, they have used some algorithms to quantify the technical debt for each issue and rule violation. And that makes sense. If NDepend has found a problem, presumably there will be a time associated with fixing it. And even cooler, they have added an interest component. Every year the problem remains unfixed, the “time to fix” will grow. The debt grows with interest! That’s darn smart, because that’s how it works in the real world. The longer a code smell or bad design hangs around, the harder it becomes to fix. This kind of quantifying debt is great, because you can use it to buttress the business case to fix bad code (which, no doubt, you have inherited :)).

As with all things NDepend, the Debt data can be viewed from many different perspectives:

Figure 8 – Technical Debt Representations

The last feature I want to make mention of is the html report that you can generate with NDepend when it performs its analysis. The easiest way to do this is check the Build Report checkbox (under the Analyze button – see Figure 1 at the top of this post for that checkbox):

Figure 9 – Build Report

The report is kinda like the dashboard, but in html format. Here’s an online example of a report from an analysis that was run on NodaTime. In addition to the sections of the report (such as Diagrams, Quality Gates Summary, Rules Summary) on the front page, there is a fly-out menu from the left which gives you even more information. This includes items such as Dead Code, Hot Spots and even Trend Charts. This report is something you can host on a server, so it can easily be made available to stakeholders etc. in your organisation.

As an overall observation, I should also point out that the UX employed on NDepend is really innovative and clever. When you have that much information coming at you, it would be very daunting and confusing if the user interface was not good. But the NDepend user interface is excellent. It’s very intuitive. Navigating around is so easy and you only have to use it for half an hour or so before you feel really comfortable with all that data. That is a small amount of time to be able to get on top of a code analysis tool like NDepend. As time goes by, you become even more comfortable with it and stumble upon more of its hidden gems. And that is before I even thought about referring to the documentation on the NDepend site, which is very detailed and complete.

There’s so much more about this tool which could be covered, such as Continuous Integration, Visual Studio team Services build integration, Code Diffs … I’ve only really scratched the surface.

For people like me whose role slowly bleeds its way into the architecture space, we need all the help we can get. Tools like NDepend really help with this. Not only is it a hands-on-tool which gives a great overview of the health of your codebase, it also acts as a tutor. It gives advice and teaches with problem descriptions and suggestions. Resharper improved my code skills. NDepend will improve my design/architecture skills.

NDepend

I’ve wanted to take a look at NDepend for quite a while now. So today I am going to write about my initial impression of this excellent static-analysis tool. To get an immediate feel for what NDepend is and what it does, there is a short video that can be viewed here.

Managed code comes with many advantages. And one of the most significant (possibly the most significant) is the mountain of meta-data that .NET assemblies carry about themselves, and those that they interact with. This plethora of information can be tapped, analysed and presented in a meaningful way which gives coders/architects a great, bird’s eye view of the state of a given code base.

This post will not be a tutorial. But it will contain screenshots and some explanations. It will fall short of being a tutorial, because I am not setting out steps from end-to-end. Think of it as a summary of one developer’s experience analysing a real .NET solution with NDepend. The solution that I will analyse is my Home Library sample application (which is nowhere near finished and currently in a state of rampant architectural experimentation).

The first thing I wanted to check out once I had run the analysis on my solution (including all of its projects) was the metrics stuff. That looks interesting to me and I immediately decided to hone in on the Most Complex... - Types metric. When you select that from the NDepend menu (NDepend > Metric > Most Complex… > Types), it loads 2 separate panes:

  1. Search Results pane
  2. Metrics pane (which shows a treemap of the results)

Once I got my head around what I was looking at, it occurred to me that it was showing me the same information, but through different prisms:

Panes

Figure 1 – Metrics and Results Panes

Looking carefully at Figure 1, we can see that the way in which that information was retrieved was by way of the query that can be seen in the Search Results pane. Now that is pretty awesome, because NDepend has its own version of LINQ called CQLinq, which is used to pull out data from the static analysis (I am not sure if it is a fully-fledged LINQ provider, as I haven’t seen the word “provider” in any of their doco – but still über cool to have your own flavour of LINQ). Their documentation about syntax etc is a very good reference for writing CQLinq.

If you hover over the various methods in the tree-view (at the foot of the Search Results pane), you will see the corresponding rectangle in the treemap light up. You can see in Figure 2 that
I have honed in on the ExpressionBuilder type, as I do recall that carrying quite a bit of complexity. By the size of the rectangle in contrast to the rest of the treemap, that complexity is represented well. Obviously, the UI-related types in this WinForms app have the most complexity, each with quite a large Initialize method for all the controls on the forms.

Hover Cause and Effect

Figure 2 – Hover Cause and Effect

Another excellent feature in the Metrics pane is a drop down list which filters the top n items which match the query. In fact, if you look over to the right in the query window, you can see Take(10) has been added to the CQLinq query in Figure 3:

Top n

Figure 3 – Top n

I was correct in my feeling about the ExpressionBuilder class, as it is featuring in that top 10. If you click on the Edit Query button in the Search Results pane (visible in Figures 1 and 2 above), it launches a pane with a text-box for query manipulation. You can then add a new query, which is a pretty cool extension point. But that’s just the tip of the iceberg when it comes to customising NDepend to your needs.

The other feature that I wanted to highlight, as something that I found really cool, is the ability to see Dependency Graphs of your code. Figure 4 shows a graph I created from the NDepend menu NDepend > Graph> View ApplicationAssemblies Only:

Dependency Graph Assemblies

Figure 4 – Dependency Graph Assemblies


That’s a really nice representation of my architecture (just as I envisioned it). You can see the UI stuff towards the left, and then as you move through the middle (the domain), you eventually hit the data stuff on the right.

You can also create one for namespaces. Check out Figure 5 below:

Namespaces

Figure 5 – Mutually Dependent Namespaces


I’ve highlighted a problem there, which the tool found, regarding mutually dependant namespaces. The tooltips (the light-yellow boxes) provide some information to assist me in hunting down the reason for this unseemly coupling issue. This is a very valuable view of the relationship between your objects. You can also drill down further by right-clicking on the connector “edges” between the nodes in the graph to look at member dependencies etc.

The really cool thing about those tooltips is that they are dynamic. When you change a query or selected-item in a drop-box, the data displayed in those tooltips changes before your very eyes.

There are a heap of other things NDepend offers, some of which will have to be the subject for a future post.

But I’ll leave the reader with this – the developers of NDepend use NDepend to develop it. To use their words, they eat their own dog-food. And a very high quality kibble it is.