We live in a golden age of static analysis. No matter what language you’re developing in, it’s likely that there’s a static analysis tool close at hand, and it might even be built into your compiler. If you’re using Go, maybe it’s staticcheck. If you’re a rustacean, you’ve probably heard of clippy. If you’re a C# developer using a modern IDE like Visual Studio, or a pythonista hacking on PyCharm, then static analysis is already built into your workflow by default. Static analysis is great because, as the name suggests, you can see issues with your code before you even run it, before it ventures out into the wide world beyond your laptop and finds its way into your customers’ hands.
In a way, static analysis is like having a senior developer looking over your shoulder, pointing out your dumb mistakes, but it’s better than that, because there’s no dealing with the senior developer’s inflated sense of self-importance or his terrible body odor (yet another argument for remote work).
Maybe you’re a real pro, and you’ve decided to pursue a static analysis solution beyond what the free tools have to offer: a tool such as NDepend, which I’m going to talk about below.
The weather on Saturday in NYC was a punishing 90 degrees and humid, so I stayed in the A/C and used it as an opportunity to play with this excellent static analysis tool. Installation was a breeze — it comes as a Visual Studio extension and once you’ve gotten started with it, it feels just like you’re clicking around Visual Studio, because, well, you are. If you’re one of the cool kids using VS Code or Rider, fear not — the folks at NDepend also provide the executable VisualNDepend.exe that you can run as a standalone app.
One thing I will say about this tool is that it is feature packed — it contains more than I can cover in an article without boring you, so I’ll only touch upon what I thought were the most standout features.
One of the first things you’ll see when you get started with NDepend is the Dashboard, and you don’t need to have an MBA to appreciate it. The Dashboard lets you view, at a glance, the health of your application. It’s the kind of thing you can wake up and look at in the morning while eating your breakfast cereal.
In the screenshot below, we see a Dashboard view for Swashbuckle, a popular open source .NET library for generating API documentation.
Almost everything on the Dashboard is clickable. By clicking on a given item, we can drill down into the details. Six Critical rules being violated looks interesting, so let’s click into that.
This brings up the Queries and Rules Explorer, where we can see which Critical Rules the code is violating. As you can see, it looks just like another panel in Visual Studio — there’s zero learning curve here.
Clicking on the rule “Exception class name should be suffixed with ‘Exception’” opens another panel that points us to the offending exception:
UnknownSwaggerDocument. How naughty.
Something I like is that the NDepend team includes documentation with each rule. The rule “Avoid non-readonly static fields”, for example, says:
You get detailed documentation such as this right inside your IDE — there’s no need to even switch to a web browser.
NDepend provides about 300 rules out of the box, but the really cool thing here is that you can define your own rules using NDepend’s Code Query LINQ feature.
Let’s say, for example, we wanted to create a rule that flags method names greater than 40 characters. Maybe we believe that such a long method name is too verbose and doesn’t belong in our codebase. NDepend actually provides such a rule already, but for the sake of the article let’s just pretend it doesn’t.
We can define our own query like so:
Notice that it’s just an ordinary LINQ query that uses some custom NDepend types. As a seasoned C# developer, you’ll be able to leverage your existing knowledge when working with NDepend.
Let’s mark our rule as Critical, because method naming conventions are important.
Our rule lives alongside the built-in NDepend rules, and when we return to the Dashboard, we see there are now seven Critical rules violated. If you’ll recall, we only had six Critical rules violated before. Uh oh.
Let’s click into that once more, and see the seven violations.
Sure enough, we can spot our custom rule.
When we click into it, we see the problematic method name, and because we defined our query to return the length of the method name, there’s a Length column there telling us that the method’s name is 46 characters.
Rules and queries in NDepend offer lots of customization that you can tailor to fit your level of OCD.
Now, my favorite feature is the Code Metrics View, because 1) it provides a high-level, configurable visualization of the health of your code, and 2) heat maps are fun!
Let’s pick on Swashbuckle again.
From the toolbar at the top, we can see that the Code Metrics View is currently configured to bring attention to methods that have a high cyclomatic complexity, with larger rectangles representing methods with more lines of code. It’s very customizable though — you can configure the metrics tied to both rectangle size and level (that is: method, field, type, namespace, or assembly).
Double-clicking on a rectangle lets us navigate directly to the method being analyzed. Sure enough, if we open a method that’s been painted red, we’ll see
if statements for days.
The Code Metrics View lets us paint our heat maps by using a range of metrics besides cyclomatic complexity. I found analyzing the number of parameters in methods to be a particularly useful one.
Here the Code Metrics View lets us easily spot a method, a constructor in this case, that looks like it might have too many parameters for its own good:
A neat feature that I haven’t seen in other static analysis tools was the Dependency Matrix. Now, I’m not going to lie, it looks a little arcane, and my eyes glazed over like donuts when I first saw it.
Fortunately though, NDepend provides a very snazzy “Context-Sensitive Help” feature that lets you navigate this Matrix with the confidence of Neo. Simply hover your cursor over a cell, and it will explain what the Matrix is telling you:
Take note of those links to documentation on the right. The Matrix can reveal several interesting dependency patterns in your code, and learning to read it can unlock lots of insight.
And as an alternative to the Dependency Matrix, NDepend also offers a Dependency Graph view, which looks especially nice on smaller projects:
Software development is more complicated than ever, so we can always use more static analysis, and while it’s no substitute for an old-fashioned code review, it can complement a human reviewer.
So if you’re a .NET developer and you’re looking for something more powerful than what Visual Studio or StyleCop Analyzers can give you, NDepend is a solid choice.
As usual, thank you for reading!