The context around this little project is that I had been asked to do a code review of a system whose architecture had been changed several times. For example, it had once achieved persistence by saving to SQL Server, but had changed to use a NoSQL store. Each time the architecture was changed, the new code tended to put in without necessarily removing all the old code. As a result I suspected that the system contained a fair amount of dead wood, and I wanted to locate this code so that it could be removed safely.
It struck me that ReSharper‘s ‘Find usages’ function could come in handy here. This feature enables a user to select a code element such as a variable, class, method or property and be presented with a list of the places where the element is used, or be told if it’s not used. I had an idea that if I could automate this feature, I could use it to generate a list of all methods that weren’t ultimately called by a production executable or website.
I achieved this by writing a ReSharper 6.0 plugin, and the developers were quite interested in it. They asked two questions. Firstly if they could run it themselves – which they could, as it was easy to install on their machines. And secondly they asked if it could be run on a regular basis. The build server was the best place to run it regularly, but unfortunately the plugin had to be run interactively – it was fired by a menu item in ReSharper. So I started trying to look for a way to make it runnable by an unattended process.
If you’re aware of NDepend, which is a product specifically designed to generate metrics of this kind, you may be wondering why I didn’t use that. In fact this is is due more to embarrassment than to technical considerations. I had actually got my employer to purchase NDepend for me, but unfortunately I had not done my research well enough to realise that the interactive version could not be run from the command line (and hence not on the build server, either) and I had asked only for the interactive version. I had then failed to make particularly good use of it and had been too sheepish to ask for the command line version as well. However, I do have supporting reasons for not using NDepend:
- NDepend is fairly expensive, and my employer would never agree to purchase it for all developers (and indeed I would never try to persuade it to do so), because they wouldn’t use it much. Therefore any recommendations that it made wouldn’t be visible to developers until they’d checked in their code and the NDepend metrics had been run by the build server or a finger-wagging architect. This would be too late for it to be an efficient corrective.
- Unlike ReSharper, NDepend analyses .NET assemblies rather than code, and this means that it doesn’t cope very well with ASP.NET websites because they aren’t compiled to assemblies by default. In order to get it to work you have to compile your ASP.NET websites and point NDepend at the bin directory. And even then, it won’t consider files that are never compiled but do have some impact on code usage, such as MVC Views.
- NDepend has a language called CQL which you can use to make queries about the usages of methods. However, you can’t create statements which are recursive. So in my case I wanted not only to report all methods which weren’t called (fine in CQL) but also all methods which were called by other methods but not ones that were ultimately called by exes or websites. This wasn’t possible in CQL. The command-line version of NDepend outputs an XML file which contains all dependencies, and I could have used that to find out what I wanted – but I didn’t have the command line version.
So there’s the background. In my next post I’ll provide an overview of the steps I took to achieve the goal.