Writing software well is something we should all strive to do no matter how small the task. Business requirements always change and the piece of code you wrote quickly to satisfy the problem will come back one day with further requirements. I cannot stress enough how important it is to apply best practices early in development as that will make the life of next developer who touches your code (and it may be you ) either a blessing or a complete nightmare.
What is the best practice? That's the beauty of it. It's always changing and what's good today might not be good tomorrow. Isn't that exciting? Best practices will vary from team to team and from company to company. As the title suggests, let's narrow it down to the .NET world and Object Oriented Programming and how NDepend can help us improve the quality of our code base.
Additionallly, this article will be leading up to a series of new articles as I personally face the challenge of taking a very old code base that has very little of the best practices and applying the latest methodologies in software development with it.
I'm proud to say that i'm now part of the Gracenote family in Australia and my challenge will be applying these methodologies as part of my responsibilities:
- Taking old code and making it testable
- Migration from TFS to Git
- Provide a Code Review Process
- Having a Build server for CI
Currently I'm evaluating a series of software to do all that, if anyone has any recommendations please do let me know! I plan to automate the entire process as much as possible and really define a workflow that will help increase the quality and value of what we deliver. Stay tuned for more.
What is technical debt? I particularly like Techopedia's definition of it:
Technical debt is a concept in programming that reflects the extra development work that arises when code that is easy to implement in the short run is used instead of applying the best overall solution.
This implies that there is a relationship between technical debt and finance. It can cost you or the company in time and man hours and a lot of frustration.
Writing easy to maintain code is by no means difficult, it simply requires diligence.
Many of us would have taken object oriented programming courses or read about interfaces and abstract classes but to truly apply them to a problem effectively comes with experience and the time. So what if we don't have that kind of experience or we want to analyze some existing code? That's where NDepend comes into play.
What Is NDepend?###
NDepend is a code analysis tool that plugs into Visual Studio. The installer itself is pretty simple and you can choose specifically which version of VS you want to install to. It will auto detect what you have on the system. Just run the NDepend.Install.VisualStudioAddin.exe and click on your VS version.
There's only one option available from the new NDepend submenu in VS and that's to attach to the existing project.
Note: NDepend will modify your .sln file
The documentation on NDepend is simply fantastic. I managed to get going even without it but all sorts of windows will popup with hyperlinks if you click on the help/documentation option in the submenu.
The website itself has video tutorials and easy to follow guides.
The most powerful feature though has got to be CQL. They have developed their own SQL like syntax for you to query your code! More on that later.
Code Analysis In Action###
You will notice that an html page also spun up aside from the dashboard. I found this to be more useful than the VS dashboard because it links you to various "problems" it found and was generally more pleasing to look at. Here's an example of a dependency matrix:
Although it does have a couple of graphical displays for visualizing dependencies, I found this to be less of a concern as we can kind of already get the list of third party packages from the .packages file. VS would warn you anyway if there was a cyclic dependency.
What really matters though are the queries that were run to generate the warnings for bad code. Check out these warnings in a sample solution loaded:
Let's click on the last item in this list and see what we get:
It even points you to which file had the 'issue'. I chose this warning in particular because there's something in the default analysis that NDepend fails to recognize: Dependency Injection.
The warning mentions that we have a class that should be instantiated. However, my IoC container does that for me and injects it into any objects that contains the Interface that class implements. But that's okay. These are all the default rules and we can turn this one off because it doesn't make sense for this solution.
That SQL like syntax that you see there is the CQL mentioned earlier. That is really the heart of NDepend on how it finds out where problematic code may exist. It goes really deep into the code and the queries can be modified to be customized for your team's requirements.
You could literally copy and paste that CQL and paste it into this window:
The people at NDepend have really made it super easy and understandable. I'm going to list the features in point form to make things a little easier to digest:
On the far left is the group of rules or queries you want to run. These happen to be the default ones.
They're categorized by the type of quality metric and inside each group is a series of more specific queries that belong to that category (the middle window).
Clicking on them populates the window on the right with the query which you can execute right away and it will point out the classes that are 'affected'.
Clicking on the class will jump to that source file
It's nice to see that at a glance if any code looking to get into production has any outstanding issues. Taking the time to really master and understand your tools is just as important as writing the code.
A nice part of NDepend is the ability to define your business rules in CQL and have it part of the build process. Using a powershell script as part of the build step process we can run the CQL for any queries we deem as business critical and have the entire build fail if it doesn't pass the CQL test. Straight from the NDepend page:
At Build Process time, when a critical rule is violated the process NDepend.Console.exe returns a non-zero exit code. For that, the report section CQLinq Rules Violated must be activated in the NDepend Project. This behavior can be used to break the Build Process if a critical rule is violated. Also, NDepend.Console.exe outputs in the $OutDir$ a file named CodeRuleCriticalResult.xml that contains the names of the rules violated. Hence, this information can be easily used by the Build Process if needed. --
Critical Rules and Build Failure
Fanastic! I definitely plan to give this a go once everything is setup.
That's it for now. I'll definitely give some more concrete business rule examples in the future with CQL and bind it all together into a CI build script once that gets going.
Thanks for reading!