As developers we deal with two kinds of software. The first kind is when we start a project fresh. It's the most fun and exciting. We get to play with new tech and implement various different solutions that, at the time, we think are the best.
The second kind of software is working with Legacy Systems - maintaining code that others have written. It's often painful, frustrating, and a lot of the time an exercise in patience - untangling a very very tangled ball of spaghetti.
The majority of what we do as software developers is centred around the second kind, the Legacy kind.
As a software engineer, diving into the cobwebs and crevices of a legacy system can be an altogether daunting task.
With complex Dependency Injection configurations it can be difficult to tell exactly what is talking to what, especially when configured outside of the code.
Naming conventions can be strange (and bad). I've seen things from "MyControlA" to "FILE_CONTROL_1X" - where nothing makes sense, and absolutely nothing reads like well written prose (as Uncle Bob would say).
And how exactly do you measure the extent of the mess that you're facing when dealing such a system? Where do you start, how much effort will it take, and what exactly can you do?
On the other hand, starting a new project, a new code base, is exciting because it's new and untainted. But without the proper controls things can get messy very quickly.
Good practice would be to set up some sort of Quality Gate in your DevOps pipeline. This is a great step to ensuring code quality - but it is dependent on the nature and quality of your Quality Gate. Can you add your own rules? And can you edit the rules that are already there?
NDepend is an essential .NET tool for both these types of projects, solving each set of problems in a unique, efficient way.
NDepend - a .NET Essential
NDepend comes in a few flavors.
- A Visual Studio Extension
- Visual NDepend - A UI Client
- A Console Application (NDepend.Console.Exe)
The first point to highlight here is the ease of use of NDepend.
- Download the NDepend zip from the official site
- Unzip it!
- Run whichever flavor you like
No messy Java installs; no issues running local servers; just, simply - run it!
Running Visual NDepend gives the option to integrate NDepend into Visual Studio or to simply run once-off analysis on a .NET Solution.
The Visual NDepend UI is clean and crisp, with the look and feel of a .NET product. Navigating the UI is trivial - I used all of the NDepend feature-set without having to look at the documentation once. Everything feels intuitive and easy to figure out.
For the purpose of this post I'll discuss running NDepend's once-off analysis on one of the legacy systems I'm currently working on.
The NDepend analysis ran under 30 seconds; a competitor product took about 20 minutes. This was seriously impressive. How good could such quick analysis be? It was fantastic - much deeper and more insightful. In part thanks to NDepend's rule-set, which is unique with very little overlap when compared to competitor products.
Analysis with NDepend generated a full report (as a webpage) that contained a staggering amount of information about the .NET solution.
The first is a series of diagrams outlining different aspects of your code base.
To understand these diagrams please see Scott Hanselman's excellent NDepend metrics placemat.
Each diagram gives a unique and very insightful look inside of your code-base.
- The Dependecy Graph and Matrix is an excellent tool to start untangling your dependencies and to start getting them flowing in the correct direction.
- The Treemap metric is great to visualise exactly where the majority of the technical debt sits in your project.
- And the Abstractness vs. Instability diagram is just altogether wild - see for yourself - visualising metrics around code complexity etc.
The next thing it generates are Application Metrics.
The most interesting metric is the time estimation for the technical debt. This is unique to NDepend - generated based on the code complexity analysis. From my own personal experience this metric has proven to be quite accurate, and extremely insightful in developer meetings - during activities such as sprint planning.
I'm of the opinion that the most expensive part of software development is technical debt - so this aspect of NDepend makes me feel like a kid in a candy store, especially with its visual aspects. It summarises the debt, giving an exact visual layout of exactly where this debt has been built up, with guidance and time estimates to fixing it.
Finally, the last result of the analysis is the Quality Gate - whether the code is good enough to get a thumbs up from NDepend (or not).
It comes with an in-depth breakdown of rules within the rule-set that have been broken.
Now, opening this report in the Visual NDepend application gives even greater insights.
Each of the Quality Gate rules in the rule-set come with excellent explanations as to why they should not be violated. This makes it a great tool for less senior developers to learn good coding practices (and maybe even some senior ones too).
As a .NET developer I love my Azure DevOps - so it's a great thing that NDepend has it's own Azure DevOps Build Task as well as its own Azure DevOps extension. The extension has all of the aforementioned metrics at your fingertips, with each of the metrics being fully interactive.
NDepends rules are created using CQLinq or Code Quality Linq. It's a trivially simple query language to learn, and allows you to write your own rules (or edit the ones that are there already). For example, the CQLinq rule
//<Name>Avoid too large methods</Name> warnif count > 0 from m in Application.Methods where m.NbLinesOfCode > 30 select m
raises a warning if the amount of lines in a method exceeds 30.
NDepend has proven to be an invaluable tool to me - dealing with legacy code, or maintaining the integrity of new projects. It blows it's competitors out of the water with performance and depth of analysis.
It has helped me tremendously in understanding software on a much deeper level - and given me insight into the murk of Legacy Code.
NDepend is a fantastic tool I would highly recommend to anyone looking for a reliable, performant, quality gate with deep and useful insights.
It's a .NET Essential.