Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Simplify Code Using NDepend

4.79/5 (27 votes)
3 Nov 2009CPOL8 min read 283.1K  
Using this article you will get the basic idea of how you could use NDepend to control/analyze your application. It allows to apply design rules and refactor code.

Table of Contents

Introduction

In today's world when you are developing a real world application with huge codebase, lots of attributes that we have to think. Few of them are Maintainability, Understandability, Clarity, Dependency, Product Superiority etc. We do lots of hard work to maintain our code, make the code well commented so that future developers might understand the code better, we find dependency between two or more assemblies and try to minimize dependency, limit the no of Lines of Code and so on and finally do testing before release the product for future use.

While doing this, we loose lots of our time which might have been used to Development for better coding.

What if everything is done without thinking of anything at all? Yes, NDepend [^] allows you to handle large project to get summary of everything at any instant. Thus, without depending upon the fact of how big the assembly is, how many types are there in your assembly, how much lines of code is there in your project; you can easily determine the quality of code and what are the sections that the code should be looked upon and Refactored.

Background

Patrick Smacchia, A C# MVP, introduced NDepend in 2007. The primary motive of NDepend is to allow the Architect to get clear idea about cross dependencies between objects, level of association between them and to find the condition of code easily. I will discuss how we can use NDepend in our application to manage our code easily.

Dependency Cycle

Many of us would agree that avoiding dependency cycle between components is the primary principle of Good Software Design. If a component A depends on B, B depends on C and C again depends on A, the component A cannot be tested or developed independently without B and C. Thus A, B and C forms an indivisible unit. This indivisible unit has high cost than the individual units when it comes to the point of maintainability of code. It is suggested that maintaining 1,000 lines of code will likely cost three or four times more effort than what is required to maintain two 500 LOC independent blocks. Thus for any rational architecture, one accepts each component being 500 - 1,000 lOC and there is no dependency cycles between those.

Dependency Structure Matrix

Dependency structure matrix is used to get the knowledge on by which extent a namespace is dependent to another. The console helps you to get the idea about the dependency between one class with another. Let us look at the picture below :

clip_image002.gif

The blue cell shows a dependency between the two namespaces in x and y axis. For example, the down left cell (0,12) shows that the namespace Spring.Proxy is indirectly using the namespace Spring.Threading with a shortest path of length five. By shortest path I mean the items are not dependent directly rather it depends on assemblies that inturn dependent on another and finally to it.
The black cell shows that there exists a dependancy cycle between 2 namespaces. For example, the couple of cells [9,7] and [7,9] reveals that the namespaces Spring.Validation and Spring.Core.* belong to a dependency cycle of shortest length five.

The red box around the black cells states that every component are directly or indirectly defendant on each other and hence creating a super - component which cannot run independently.
You can refactor your code structure to eliminate the dependancy between code. You can read more about Dependency Cycles from here [^] .

Code Query Language

Another useful and unique feature that NDepend provides to us is CQL. It allows to write queries on .NET objects. This is really helpful to deal with large amount of codebase. We might use simple SQL like query to find our desired need. For instance, suppose we think to get all methods that have more than 200 number of lines (The idea is always to have less than 200 no of lines in a single method for better code structure). We might use simple Query like:

SELECT METHODS OUT OF
NAMESPACES "MyApp.MyNamespace1","MyApp.MyNamespace2"
WHERE NbILInstructions > 200
ORDER BY NbILInstructions DESC

Thus it will search within MyNamespace1 and MyNamespace2 and try to find the methods that are having more than 200 LOC and list in order of LOC in the console.
If we want to get types that implements IDisposable we write :

SELECT TYPES WHERE IsClass AND Implements "System.IDisposable"
In addition to this, CQL supports inbuilt functionality to incorporate rules to your .NET applications.

Practical Examples on NDepend

After all those initial discussion it is the time now to grab some practical knowledge on how you could use NDepend. I will discuss with other UI elements provided within the NDepend console when needed.

1. Compare Builds of Same assemblies

The unique feature of NDepend is to provide a quick overview of all the changes that are made between two builds. NDepend gives a superior UI to compare between two builds. We can easily make use of CQL to see what are the methods that are changed, what are Removed, what are changed and so on. Let us give a quick example on that :

Compare1.JPG

In the above figure, you can see how to start comparing builds between assemblies.

  • Start Visual NDepend. Choose 2 version of a CodeBase.
  • In the dialog that appears, select 2 assemblies which you want to compare. You can also select more than one assemblies which has dependencies between one another. And Click OK
  • After initial Build Process, it opens up the Compare console as the figure below.

    Compare2.JPG

  • In the figure you can see 4 sections :
    1. Class Browser: In this section, the console shows the hierarchy of class structure to determine what are changed in assembly. As you can see, it clearly demarcates each Namespaces. StrikeThrough Namespaces denotes present in Older version, but removed in newer version; Underlined means Modified in Newer version., and Bold nodes are newly added.
      Thus from this tree we could have clear idea about what is changed between the two versions.
    2. Metrics : It represents the Metrix of all the methods that are defined in the two assemblies. If you hover mouse over any of this section it tells about the No of lines and the name of the method, as shown in the figure above.
    3. Info : This section shows the summary of the currently selected Item, such as Number of IL Instructions, Lines of Comments, No of Lines, Cyclometric Complexity etc.
    4. CQL Query Section This section allows you to define custom CQL queries to filter output. You can define CQL like :
      SELECT NAMESPACES FROM ASSEMBLIES "XXXX.AssetTracker.Data" 
      WHERE NbLinesOfCode > 100
      It will list all the namespaces under Assembly XXXX.AssetTracker.Data where Linesofcode exceeds 100.

    These 4 sections could be used to grab the entire knowledge about all the changes that are made between the two assemblies.

compare3.JPG

Instead of typing the queries yourself, you can also find the most appropriate queries by right clicking on the Namespace and What was changed? as shown in the figure above. The types will be listed in the CQL Query Results for you.

Analyze our Code

After comparing codebase, let us analyse our code. To Analyse, choose Analyze a set of .NET assemblies from the initial screen of Visual Ndepend console.

analyze1.JPG

From the Dialog box that appears, choose the dlls that you want to analyze and click Ok. The process will build the assemblies, analyze it and produce you a report. If you see the report, you could get a clear idea of what is done in those dlls, Dependency matrices etc.

To inspect more let us see the picture below :

analyze2.JPG

SELECT TYPES FROM ASSEMBLIES "XXX.Framework" WHERE IsPublic

Here the CQL returned the output of all the Namespaces which are public in the Assemblies. The List says there are 60 types of such Types with each defining the no of lines in it. The panel below gives the analysis of search statistics.

Adding Constraint in Code

In addition to all those features, NDepend also allows you to integrate with Visual Studio. From the console Click on Install to open up this window:

Code1.JPG

The dialog installs NDepend plugin to Visual Studio. It also allows you to install Reflector into visual studio. The buttons appear in the dialog will help doing this.

Now from your Visual Studio IDE we can get access to CQL queries and easily check Dependancy matrix. Anytime just right click on the code and you will find NDepend Context menu option.

code2.JPG

Thus we can also easily access the CQL queries directly from Code. This gives additional benefit to have better grasp on our code while writing. NDepend also allows you to write Constraint directly into your code. It generally uses XML file to store this constraint. IF you add NDepend.CQL.dll to your project, you might add

[NDepend.CQL.CQLConstraint("WARN IF Count>0 SELECT METHODS WHERE NbLinesOfCode > 400")]
to directly warn me when the code compiles without following the constraint.

Download this Tool

To download this tool follow this link. [^]

For Further Reading

Code Query Language [^]
Tips and Tricks [^]
Metrics Definitions [^]

Conclusion

First of all I must thank Pattric, to let me try this and also giving me the honor to write about the great tool he developed. There are lots of terms here which are very new to me and learned while learning. So if I make any mistake, just let me know, so that I could update the article.

History

Initial Build : 4th November 2009.
This is the initial introduction of NDepend. Comments are welcome.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)