Evaluating NDepend on current code base Part 1

A while ago I was asked by one of NDepend's founders to evaluate any .NET code base I wanted with NDepend and write a blog post about it. It turns out I came up with a two-part post. TL; DR Oh boy....
Photo by geralt on Picabay


Enter 3 years old WPF project

Without revealing the nature of the specific project I would just say it is a feature rich client, with UI elements customized to the customer's needs. It is written using MVVM, some third party grids and communicates with an SQL Server database via a classic  DAL class library. All and all the project is comprised of one executable and one DAL assembly.

So off I went and added the necessary assemblies to a new NDepend project and let the analysis run. Given the size of the project it was pretty swift and started off with a a dashboard (or at least this is the view I chose to start from).

NDepend desktop Dashboard

At the same time a very nifty HTML based dashboard popped up in my browser

NDepend HTML Dashboard


The dashboard (as expected from its name) gives one a very good 10000 feet overview of the state of the code base. The first thing that drew my attention on the HTML dashboard was the Abstractness vs Instability graph... Although the Treemap Metric View looks mostly clean (green) the Abstractness vs Instability tells a different story...

NDepend Abstractness vs. Instability

In order to get accustomed to the tool I examined the DAL assembly first. I took a deep breath and set out to see what rules where broken. A little bit of drill down brought me to 14 types and 4 methods in the DAL violating some rule... How hard can that be?

The elusive "Avoid namespaces mutually dependent"

I am not a native English speaker. I do, however, consider myself pretty fluent in the English language and this one I had to run through my head a bit. After reading about it in NDepend's docs, which thoroughly explain how to investigate the issue and acted as per the docs, I got the gist of it. There is a circular dependency between namespaces. One that is not direct or easy to find.

How come the tool finds  a possible circular reference between two namespaces and I do not see it in code unless I am using the tools provided by NDepend? Instead of dismissing the error I took out the good old pen and paper and started writing down the dependencies, inheritances and implementations between two offending namespaces (out of 14 violations). This was more for ducking it out to myself than lack of documentation. When I was done writing down it hit me... Spaghetti code one step away from adding the meatballs. Here is a partial diagram

Spaghetti...


In one of the cases the solution was pretty simple... Just change the namespace in one interface and the code is untangled. In the DAL assembly however lies the hint for the mess to come. Not all 14 violations where so easy to solve.

More code smells

If you take a close look at the dashboard image there are some more problems there. Some of them denote long types, long methods or long names. Pretty easy to solve. Some of them are warnings that the U.I should neither use DB types nor the DAL directly. I agree on the former. I can argue the latter. And I think that the makers of NDepend where right to make this a warning and not an error.

Ideally the U.I layer would communicate with a service which communicates with the database. Then again ideally none of us likes to inherit other coders code smells; We like to make our own mess...

Some unwanted dependencies

One more thing that I checked out was the overall types dependency graph. I discovered that the DAL has direct access to other domain's APIs as well as direct access to message queues. This may not be a broken rule on the static code analysis but it is bad architecture.

This definitely not good architecture...


Exit DAL part of 3 years old WPF project

"Well..." I thought to myself, "this wasn't so bad. Maybe I will be lucky and the 400 offending types in the actual executable are easy to fix like the first one I checked". Was I right or wrong? On to Part 2.

Comments

  1. Despite the fact that the whole project consists of one file, it does not become simple and easy, on the contrary it is even more difficult and problematic for team work.

    ReplyDelete
  2. The post is not about this being in one assembly or many. If I was to write a post about that I would end up writing a 5 part series. Nevertheless some rules can and should be followed even when this is the case. It is obvious that this is not the case here. Rules where broken, if they were in place at all.

    ReplyDelete
  3. I suppose that all work you have done is actually great! You provided a lot of facts and arguments for and against! I am delighted by the description!

    ReplyDelete
  4. The article provides a detailed and practical evaluation of NDepend against a real three-year-old WPF code base. I appreciate how the author moves beyond the dashboard overview and investigates actual architectural issues, including namespace dependencies, code smells, long methods, and layer violations. The explanation of tracing circular dependencies with NDepend and even mapping them manually makes the discussion especially useful for understanding real-world code quality analysis.

    The exploration of the DAL assembly and the “Avoid namespaces mutually dependent” rule demonstrates how static analysis can reveal architectural problems that may not be immediately visible from the source code. The examples involving interfaces, namespace changes, UI-to-DAL dependencies, and service-layer architecture also show how code quality tools can guide refactoring decisions. These practices can complement structured learning through Python Coding Course, particularly when developing an appreciation for maintainable and well-structured software.

    ReplyDelete
  5. The discussion of additional code smells is equally valuable because it distinguishes straightforward issues, such as long types and methods, from deeper architectural concerns involving dependencies between the UI, DAL, and database layers. I also like the author’s recognition that not every warning has an equally simple solution. This emphasis on examining dependencies carefully and improving code structure provides useful lessons for developers undertaking Python Coding Training while building maintainable applications and learning disciplined development practices.

    ReplyDelete

Post a Comment

Keep it clean, professional and constructive. Everything else including ethnic or religious references will be removed.

Popular posts from this blog

Running an Asp.Net Core 2.* Web API as a Windows Service

Reviving old hardware en mass or: How I Learned to Stop Worrying and Love the ZorinOS Linux Distribution

Evaluating NDepend on current codebase Part 2