Whenever I takeover a legacy project, the first thing I try to do is to see what I’m getting myself into this time. 🙂
It’s been a long journey for me in the world of bits and pixels so I have my own scales and “Reserved Words” like Thom Holwerda here;
While it may be enough for you an your buddy who is next to you analysing the same code, it is not enough for professional communication.
It’s easier to understand this report below. I managed to get a lot of refactoring / rewriting budget with this graph during the years.
As title hints, this is one of NDepend‘s graphs and believe me this looks high level and quite easy but it is a life saver. They updated 2019 version with really nice features and it’s working quite fast with large solutions.
I tried it with a quite big 10+ years solution that has millions line of code and 700 projects. Full analysis took 3-4 minutes with 16GB RAM and a 450mb/s SSD and the good thing you don’t have to load anything after. Once it finishes with the analysis it’s really fast. I didn’t have much time to play with the console application but it seems with this speed I can use it in my CI after every commit to see how much the quality affected.
So let’s talk about some tips and tricks about doing an overview analysis and how to plan ahead.
The tool NDepend is a paid software. You can check the prices here.
But it has a 14 days trial period and with full features. That is enough to check if it’s working for you. You can download NDepend here.
I used DNN – DotNetNuke code as an example to provide these analyses. You can check and download the open source project here.
The download procedure is straightforward, NDepend comes as a small zip file. You don’t even need to install anything. Just extract the zip to a folder and start using it by clicking on VisualNDepend.exe file.
It has a VS Extension but I personally try to keep my VS as clean as possible so I haven’t tried that one.
When you click the executable the main window looks like this.
If you create a project, you can continuously check the differences with each iteration. If you don’t, you can just do a One-Off analysis. This looks trivial but check closer, you even have an option to Compare 2 versions of a code base. So there is a lot jewels in this tool to cover depending on your workflow.
After selecting One-Off Analysis from the left, you select the solution .sln file or .csproj file to analyse. This brings up a window with all the assemblies in that solution.
I selected All here, to see what we’ve got. If you select Build Report, it will create a web folder with a large report. You can share it, zip it etc.
The analysis is really fast. This time NDepend nailed it. Larger projects don’t even get 5 minutes to analyse.
You get a web report like this. But I always start my analyses with the Desktop Application. You can get the same interactive report in the app.
Then on the desktop app when you select to go to the Dashboard you get this screen. Yes it’s a little bit intimidating. But this is an overall view with some statistics.
On the left you see your class browser. That does nothing relevant on this dashboard screen. It’s a part of GUI.
Checking the Dashboard, you’ll see that it basically scores your Technical Debt and gives you a rating. It even estimates man/days to get to the next score level. I find this feature useless, but maybe it can be used to compare efforts and have the fastest and most effective selection. I have never used it.
Remember this is a one time analysis so the graphs on the right and bottom are not relevant for this example. It created the project in the temp folder and it will be discarded later. If you create a project and save it and reuse it to analyse your solution periodically, then these graphs start to make sense.
For my quick analysis, on this screen I check only Quality Gates, Rules, Issues briefly and then I go to the details directly from the tabs at the bottom of the dashboard.
First thing I check is the Metrics screen. I believe this gives me the most insight. Here is how to analyse it;
- First check how the image is seperated into squares with grey borders. Some of them are large, some of them are small. This shows how much code you have in that project. You can seperate them easily because they have titles as project name. Let’s call them “Project Squares”
- The next thing is the gradient colored small squares inside these “Project Squares”. These represent whatever you select from the combo box on the top of the screen saying “Size”. You can select;
- # IL instructions
- Cyclomatic Complexity (CC)
- IL Cyclomatic Complexity (ILCC)
- IL Nesting Depth
- # Methods
- # Overloads
- For short analysis I always check Lines of Code and Cyclometic Complexity. For me these are the best filters to have an overview of the solution.
- Also you can select how deep you filter from the Level combo box above. The default is Method but you can select namespace or assembly to have an overall view. I leave it as it is because we already have “Project Squares”
- If you have a lot of complexity on a method, the color will be red. You can select the intensity against the filter you’ve selected on the right. This is actually nice. Because maybe you are only interested in the most complex code to fix. Just increase the intensity for red color to your liking. Now your filters will change color and you will have fewer targets. Now you know where to refactor, where to attack first. Instantly you have a plan to increase code quality after few minutes.
So we talked about Cyclometic Complexity and Lines of Code. I know that you are thinking LOC does not mean anything. But remember we are doing a preliminary analysis to a DotNet project we have never seen before. I found LOC helpful for tackling too large assemblies. If you are constantly changing and deploying things in that project then you might want to consider seperating large monolith projects into many small NuGet packages. Which can be developed, tested, deployed separately.
Cyclometic Complexity is a way to quantitatively measure how is the part of your selection is complex. This is mostly used for a method, or a class. This topic goes really deep for a better understanding you should google it. But basically if you have too many “if – switch” statements, “for loops”, method calls etc. basically “Too much flow control elements” in a function, that makes it hard to read, hard to maintain, hard to reuse, hard to test. You need to fix these things to improve your code quality, the stability of your system and also the sanity and productivity of your developers.
I always believe in this quote:
“To go faster sometimes you need to slow down first”
We used this motto in many projects and it was worth the investment.
After playing with this report and having things sorted out here, now you have an understanding of the solution in hand and you know where to target first.
If you click the small squares here you will be directed into Visual Studio and to that function. It’s quite nice to have this functionality. You are connected to your code and it’s a full loop. Just check few methods and see the code quality, coding standards, magic numbers in the code etc.
The next step I check the Dependency Matrix tab.
This is a representation of namespaces on the columns and rows. You can drill down these names to the class member detail. Here you will see how many dependencies a namespace/class/member has. You can check which modules are the most used ones. What is your core functionality, how many references it has.
One of the worst things you might get is your backend code referring to your UI code. But you can detect those kind of dependency issues on this report easily.
Even worse, you can have circular dependencies;
A circular dependency means that these are no longer two independent projects (because there it is impossible to build only one of them). You need to either refactor so that you have only a one way dependency or you should merge them into a single project
I also found another use of this report; When you decide to move things around. Remove a 3rd party assembly from your solution, it helps you to overview the dependencies and work to be done. So you can use it in your routine refactoring cycle to quickly analyse the effects.
Rules and Quality Gates
You have a section on the bottom of the screen for the Project Rules
You can use bottom part to filter rules like “Avoid methods too big, too complex” or “Avoid types too big” and see the details on the left. You can click and go to code or right click and check these classes in the dependency matrix if you want to continue visually. NDepend even has a query section that you can use linq to filter your rules. You can check the official documentation here. It’s fantastic but I never needed it because when I go over a level of quality and when it’s maintainable, I rewrite that section of the solution with TDD, so it’s already using all the best practices.
Let’s go back to topic. I found an easier way to analyse the solution quickly;
If you go back to the HTML Report, you will see a section named “Rules summary”. This is a section that shows all the violated rules, click to the title and see the details.
Also there is another section called “Quality Gates summary” in the same report;
This one shows the “Critical Rules Violated” and “New Blocker / Critical / High Issues”. When you click one of these you will go to a more detailed report page;
So now you have all the information you need to know about the quality of your project. You have an overview where things might go wrong, you even have some SMART actions to take. If you’re used to work with NDepend like I do, it only takes 30 minutes and for me it saves hours.
There is more to it; You can put your tests and test coverage reports into NDepend and have more correlated information about the parts that require testing and their quality, dependencies etc. in one report.
You can check all the NDepend walkthrough videos here. There is a lot more to discover about this tool.
Note to myself: Learn to use the NDepend CLI and try to integrate it with my Continuous Integration.
This is how I quickly analyse a project when I take over. I do the same things periodically to compare the results to see the quality improvements.
What I like about NDepend is;
- It’s visual, I can share my findings with non technical people
- Latest version is blazingly fast. Works great with the largest projects
- Closed loop, you can browse your code and see details while analysing it
- It comes with a small package. You don’t even need to install it
- Integrated with Test Coverage results
- Integrated with VS 2019
- These guys are there from the very beginning of DotNet with a great tool and I support them
Happy coding all 🙂