Welcome to the brand new NDepend blog! This blog will talk about NDepend of course, announcements, directions, features advanced usage, but this blog will also talk about related topics including, coding tricks, .NET static analysis, methodologies, theories behind features and .NET development tooling industry in general.
Choosing the right set of new features
Today I’d like to talk about the just released NDepend version 6. So far our major releases schedule followed the Microsoft Visual Studio release schedule, and Visual Studio 2015 is actually in Release Candidate period. NDepend v6 is the result of 18 months of hard work. After 11 years of development, NDepend reached a certain level of maturity. Yet there are still many new potential features and improvements possible. We found out that the most sensitive part for this version 6 was actually to chose carefully the set of new features and improvements we’d like to offer to users. Hopefully, once version 5 was published in October 2013, we got inspiration from the Visual Studio User Voices and opened our NDepend User Voices. As a matter of fact, version 6 new stuff reflects well the most demanded features that have just been marked as completed.
Build-Process Workflow Integration
Clearly users were asking loud for more NDepend integration into their build-process automated workflow. So far, users were running NDepend.Console.exe, gathering the report and the information: is there any critical rule violated that should make our build fail? (this info can be obtained NDepend.Console.exe exit code). Users were asking about more information to be shown right inside their build-process tooling. There are many build-process technologies and the most demanded one were TFS, TeamCity and SonarQube. Hence we’ve collaborated with world-class experts of these technologies to deliver build-in integration. We hope that proposed integration will address most scenarios, and we are committed to support further versions and enhance the feature set.
Enhanced Visual Studio Integration
It was not surprising that users wanted more build-process integration since during the last year the bulk of our efforts were devoted to tooling for developers inside Visual Studio. NDepend was integrated in Visual Studio through the VS Addin technology because of a choice we’ve made in 2009. At that time VSIX (VS package technology) was immature and we had to support VS2008 and VS2005, hence VS Addin was the right choice. Time passing by made this initial choice less and less relevant, the VS Addin technology didn’t get any improvement from Microsoft and worth, implied a few glitches like random bug, but worth, the impossibility for VS to remember NDepend windows layout across execution. This was a pain for NDepend users and they ended up asking it loud on the User Voice to remember VS Windows Layout!
With version 6 NDepend relies on the VSIX technology to integrate in VS 2015, 2013, 2012 and 2010. (Should we mention that MS deprecated the VS Addin technology in VS 2015?). Anyway now thanks to VSIX we are able to offer a smoother and more reliable VS integration with windows layout remembering and with new features like the possibility to attach the NDepend project to a .suo file (and not only .sln file) and full support for NDepend commands keyboard-shortcut.
There were also 3 VS build featurettes proposed by various free VS extensions, and we figured out that ourselves were pretty much addicted to it. We decided to include them in the NDepend VS package, this way we will be sure to always have them at hand, and with a bit of luck, NDepend users will enjoy them too 🙂
.NET code ruling is the central feature of NDepend. We had many feedback from users about how to improve existing default code rules, mostly to reduce the number of false-positive reported. hence we’ve refactored around a third of default code rules based on their recommendations.
While doing so we figured out we have been a bit too geeky. This is great that NDepend code rules are actually editable C# LINQ queries that can contain some comments. But for many users this didn’t convey enough information about why a rule actually warns, why abiding by a specific rule will enhance their code, and how to fix a violation of the rule. Hence we’ve added the possibility to add 2 formatted texts in a NDepend rule source code comment through <Description> and <HowToFix> tags. This has been a great opportunity for us to write out about each default rule and provide users more explanations. Both in UI and in report, the user can chose to see the Description/HowToFix, or the rule C# LINQ source code.
Another need that users were asking loud in the User Voice, was the possibility to share some rule set among several NDepend projects. Typically a Company has several code bases analyzed each by a NDepend project, and what users want is a Company-level quality profile that can be applied to each code base. And taking account that NDepend makes easier than any other tool to define custom rules on .NET code, users wanted even more to define custom quality profile shareable. We addressed this need in NDepend v6 with the possibility to define rule files that can be shared among NDepend projects.
Code Metrics Visualization
NDepend already had code metrics visualization with treemaping and we decided to add coloring. The idea is that we can then visualize two code metrics, one represented by rectangle area, the other one represented by rectangle color. For example, the screenshot below shows NDepend version 6 code coverage by tests in a unique, yet convenient and accurate way.
- Rectangles represent methods,
- Rectangle area is proportional to # Lines of Code,
- Rectangle color represents percentage code coverage by tests
I hope this picture helps understand why we wanted to offer users this feature. At a glance, colored treemaping can help grasp information that would be hard to get through another mean. Despite the fact NDepend v6 code base is 82%+ covered by tests, we can identify aggregation of red rectangles that shed light on regions of code not enough covered by tests. I believe no other tooling can offer such level of details, and while developing this feature, I was really looking forward what it has to say about our own coverage & testing work!
And as usual we like to make the various NDepend features interact. Hence not only you can visualize any two of the many NDepend default code metrics set, you can visualize custom code metrics defined through C# LINQ queries, and you can also highlight the result set of a code rule or a code query. Hence if we query for complex methods, we can filter complex methods match on the colored treemap:
Let’s mention that since we think that code coverage by tests is one of the most important code quality data, we also added dedicated UI candies for it in code query result:
Improvements that had to be made
A product belongs to a constantly evolving environment. This means that with years, some features that were working fine need to be revisited. Several of such needed improvements / fixes have been achieved with NDepend version 6.
Support code generated by C# and VB.NET compiler: Version after version, C# and VB.NET languages increased the amount of syntax sugar offered to the user. It started with C#2 anonymous methods and iterators, followed with C#3 lambda and anonymous types and then C#5 async support. These language constructs constraint the compiler to generate extra methods and types. And since these constructs are pretty much used, numbers of these generated elements accumulate in the IL code. And NDepend mostly relies on IL code to get code information. Hence the NDepend code model included all these generated methods and types and this started annoying the user, mostly interested by its own code. NDepend now fixes this. Simply getting rid of these generated elements was not an option because they actually contains some user code. Hence we developed some heuristics to merge these generated elements in users classes and methods that contain the code that provokes the generation by the compiler. This way there is no compromise, all the code model data is preserved, including: Code metrics (# Lines of Code, Percentage Coverage, Cyclomatic Complexity…), dependencies and diff.
Better async support: The async language construct comes with a specificity that provoked some NDepend issues. The user code is actually embedded by the compiler in a generated method that overrides the virtual method IAsyncStateMachine.MoveNext(). Hence the IL code invoking this MoveNext() generated method is bound with the interface abstract method and not with the implementation. The calls toward the async method are then lost in IL … ans so in the NDepend code model. Thanks to the heuristics wrote for the previous point, NDepend analysis is now able to track properly callers of async methods.
Support for high-DPI: Nowadays hi-resolution monitors (like 4K monitors) become affordable and as a consequence, more and more developers work with high-DPI Windows settings. High DPI means that the density of pixels is higher and as a consequence more pixels are used to represent a graphical element (text, bitmap…). The NDepend UI is mostly based on Windows Form and GDI+ and these technologies don’t scale well by default when Windows is set with high DPI. Since some users started to ping us about this problem we decided to re-lift the whole NDepend UI to make it works with DPI settings from 100% to 250%. This has been the opportunity to enhance some graphical elements and to learn some Windows Form and GDI+ high-DPI practices. I’ll try to summarize these findings in a future blog post, because browsing the web, I can see that it is a pain for many developers.
Visual Studio Theming: From our production statistics most of users consume NDepend for Developer features from within Visual Studio. So far the NDepend UI themes didn’t fit perfectly the various Visual Studio default themes, this includes Light, Dark, Blue and VS2010 default themes. Hopefully NDepend menus/bars/docking… elements are based on the DevExpress WinForm library and their latest version included these themes (and some more). Hence upgrading to the highest version of this framework did the trick.
Analysis improvements: Some improvements had to be made concerning analysis. One of them concerns resolution of assemblies to analyze. A NDepend project references a set of directories and a set of assemblies names (without file extension). At analysis-time, assemblies to analyze locations are resolved from these two sets. If multiple copies of an assembly were found, either all copies had same bits and NDepend took one of them, either some copies were different and NDepend emitted an error resolving the assembly, because we use to consider this situation as a serious deployment problem. However with time, new technologies like Windows Phone or Portable Class Libraries appeared, and they actually provoking such situation during valid scenario. Hence, when detecting such situation, NDepend v6 now uses an heuristic to resolve the proper assembly occurrence, based on the assembly version, assemblies referenced and file size.
We are very glad to have been able to pack all these in NDepend version 6.
We hope you’ll enjoy using this new version just as much as we enjoyed making it 🙂