Analyzing RavenDB 4.0 with NDepends

time to read 4 min | 648 words

I have a… difficult relationship with NDepends, on the one hand, it is an invaluable tool to provide you with good insight into your project. On the other hand, I don’t always agree with its recommendation and I have to teach it what I consider valuable. In my mind, it is the kind of tool that you reach for when you need the Expert Mode.

We use it for exploring our API surface area and seeing that it makes sense, to validate breaking changes and in general to get detailed view into troublesome spots in the codebase.

For example, it pointed out this guy as having to many parameters. I can’t say that I disagree, and it is a prime candidate to refactor to make it simpler.


On the other hand, it didn’t get to be this way by accident, it was added to slowly over time. Each new feature or bug fix needed just a bit more, and this grew and grew. At this point, however, this is extremely stable code that rarely changes, and modifying it will take a lot of work.

Just having tools around doesn’t mean that you get to turn off your head Smile.

One important thing is that if you are considering NDepends, you probably want to start doing so very early in the project lifecycle. One of the things that I find most interesting in the new version is the notion of estimated debt. Here is what this looks like for RaveDB 4.0


And here is the value for RavenDB 3.5


This is composed from estimated amount of effort that you need to put to fix things.

The really interesting part is that it does a pretty good job of finding troublesome locations even when you don’t have history / coverage information. For example, here is the list from RavenDB 3.5:


I find it highly amusing to see this. Mostly because the client side implementation is more complex (and are more frequently modified).

Digging a little bit deeper give us this:


And this is where I start arguing with the tool. Or, to be rather more exact, I have more information than NDepends on this usage. AsyncServerClient is how the entire client talks to the server, so it isn’t cohesive and it is certainly too big, but it is pretty much by design.

The details about boxing / unboxing, however, are much more interesting, and it is where you can start doing a lot of interesting things. In particular, you can customize NDepends to give you a lot of details and enforce rules about your codebase.

For example, given our recent need, here is all the big structures in our code:


You can do that for exploring, or you can add that as a rule (warnif).