Over a million developers have joined DZone.

Managing Code Analysis Statistics With the NDepend API

DZone's Guide to

Managing Code Analysis Statistics With the NDepend API

You can use the NDepend API to enhance your ability to generate, track, manipulate, and export important information about your code.

· Performance Zone ·
Free Resource

Sensu is an open source monitoring event pipeline. Try it today.

If you’re familiar with NDepend, you’re probably familiar with the Visual Studio plugin, the out-of-the-box metrics, the excellent visualization tools, and the iconic Zone of Uselessness/Zone of Pain chart. These feel familiar to NDepend users and have likely found their way into the normal application development process. NDepend has other featuresm as well, however, some of which I do not necessarily hear discussed as frequently. The NDepend API has membership in that “lesser known NDepend features club.” Yes, that’s right — if you didn’t know this, NDepend has an API that you can use.

You may be familiar, as a user, with the NDepend power tools. These include some pretty powerful capabilities such as duplicate code detection, so it stands to reason that you may have played with them or even that you might routinely use them. However, what you may not realize is the power tools’ source code accompanies the installation of NDepend, and it furnishes a great series of examples on how to use the NDepend API.

NDepend’s API is contained in the DLLs that support the executable and plugin, so you needn’t do anything special to obtain it. The NDepend website also treats the API as a first class citizen, providing detailed, excellent documentation. With your NDepend installation, you can get up and running quickly with the API.

Probably the easiest way to introduce yourself is to open the source code for the power tools project and to add a power tool, or generally to modify that assembly. If you want to create your own assembly to use the power tools, you can do that, as well, though it is a bit more involved. The purpose of this post is not to do a walk-through of setting up with the power tools, since that can be found here. I will mention two things, however, that are worth bearing in mind as you get started.

  1. If you want to use the API outside of the installed project directory, there is additional setup overhead. Because it leverages proprietary parts of NDepend under the covers, setup is more involved than just adding a DLL by reference.
  2. Because of the point above, if you want to create your own assembly outside of the NDepend project structure, be sure to follow the setup instructions exactly.

A Use Case

I’ve spoken so far in generalities about the API. If you haven’t already used it, you might be wondering what kinds of applications it has besides simply being interesting to play with. Fair enough.

One interesting use case that I’ve experienced personally is getting information out of NDepend in a customized format. For example, let’s say I’m analyzing a client’s codebase and want to cite statistical information about types and methods in the code. Out of the box, what I do is open Visual Studio and then open NDepend’s query/rules editor. This gives me the ability to create ad-hoc CQLinq queries that will have the information I need.

From there, I have to transcribe the results into a format that I want, such as a spreadsheet. That’s fine for small projects or sample sizes, but it becomes unwieldy if I want to plot statistics in large codebases. To address this, I have enlisted the NDepend API.

Chose an NDepend Project

Okay, so what do the mechanics of this actually look like? It involves writing surprisingly little code since NDepend’s API itself does a lot of heavy lifting for you. First up, consider the code for choosing a project, shown below. I invoke this from a command line application I have that generates my spreadsheets.

private static extern IntPtr GetConsoleWindow(); 
internal static IntPtr MainWindowHandle {     
  {         return GetConsoleWindow();     } }

As you can see, this requires only three lines of code in the method, with the MainWindowHandle property included for reference. NDependServiceProvider is the star of the show for getting you references to the NDepend API types you’ll need to do the lifting. Here, you just get the project manager from the service provider and then use that to pop the NDepend “choose project” dialog. That’s it.

One point to mention here, though, is that the NDepend API depends on the use of this out parameter for project so you want to preserve this if you’re abstracting it out to methods or classes. You may encounter a runtime error otherwise.

Run an Analysis

Once you’ve got a project open, running the NDepend analysis on it is easy. Take a look at my method below for dumping information to a CSV file.

private static void DumpToCsv(IProject project) {     
  IAnalysisResult analysisResult = project.RunAnalysis();     
  var report = new ArbitraryReport(analysisResult.CodeBase);     
                    report.GenerateIcebergAssembliesReport()); }

All you need to do is take a project in and call project.RunAnalysis(). Can’t get much simpler than that, huh?

ArbitraryReport is a class that I’ve created for my own assessment purposes. It takes an operates on a type called ICodeBase. So, I run the analysis to get a result and then I pass that result into my report creator class. I then use that report creator to generate a CSV report that I want. In this case, I’m gathering stats on something I call iceberg assemblies (assemblies where most of the action takes place in hard to access methods).

Using CQLinq in C#

I’ll show you one last snippet for using the API. This snippet contains the aforementioned GenerateIcebergAssembliesReport logic, and it makes use of a Nuget package to simplify creating CSV dumps.

public string GenerateIcebergAssembliesReport() {     
  var assemblies = 
    _codebase.Assemblies.OrderByDescending(a => a.NbLinesOfCode).ToList();     
  var rawResults = assemblies.Where(a => !a.IsThirdParty && 
                                    && a.NbLinesOfCode > 0).Select(a =>          
         FanIn = a.AssembliesUsingMe.Count(),             
  TotalLines = a.NbLinesOfCode,             
  ChildMethodCount = a.ChildMethods.Count(c => !c.IsPubliclyVisible),            
  Hidden = a.ChildMethods.Where(c => !c.IsPubliclyVisible).Sum(m => 
  TotalChildLines = a.ChildMethods.Sum(m => m.NbLinesOfCode)         
}     ).ToList();     
  return rawResults.Csv(rr => rr.Name, 
                        rr => rr.FanIn, 
                        rr => rr.Hidden, 
                        rr => rr.Hidden.Value / rr.TotalLines.Value, 
                        rr=> rr.TotalChildLines); 

First, I obtain a collection of assemblies from the codebase — assemblies that are not third-party and are not test assemblies. From there, I select those assemblies into the collection in which I am interested.

This particular method creates a report containing the assembly names, their fan-in, their total lines of code, their number of publicly visible child methods, their number of non-publicly-visible child methods, and then the total lines of code in the assembly. For the purposes of this particular report, that gives me all of the interesting data.

This Is Power

All of this may seem relatively straightforward, but I assure you that it has changed the way I do client codebase assessments. I love CQLinq, and I love the way the NDepend Visual Studio plugin lets you manipulate, visualize, and have everything at your disposal.

However, as any tinkerer and software pro knows, the longer you rely on a tool and find it indispensable, the more you tend to want to extend it and automate beyond it. That, after all, inspires the entire concept of the API. Making use of the NDepend API can dramatically enhance your ability to generate, track, manipulate, and export important information about your code.

Sensu: workflow automation for monitoring. Learn more—download the whitepaper.

c# ,ndepend ,api ,performance ,code analysis ,statistics

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}