Code Metrics: An Introduction to Visual NDepend

In the second half of April I got an Email from Patrick Smacchia. I was very surprised, I mean, I’ve follow Patrick’s blog for some time and I though “this guy is really smart” so I was excited about getting in touch with him (starting from his side by the way), and while I’ve heard of his product Visual NDepend, I’ve actually never tried it and neither paid too much attention about the product itself. It was embarrassing because he was kind enough to offer me a Pro License to try it, evaluate it and see if it was functional and useful for me.

I said “Yes! Of course!”. Then started doing some research and reading and found about what was it for and how could I use it. Around that time, Scott Hanselman did his Hanselminutes Podcast 163 – Software Metrics with Patrick Smacchia so I was very excited and listened to the show about 3 times (sound was not that good, I think Patrick was not on a good phone line) and really got me into the code metrics thing.

image

So, here are my initial thoughts about Visual NDepend. I must say up front that I’m far from being an expert and that I have called this post “Introduction to Visual NDepend” for the same reason. I expect to use the tool more and be able to express myself in a more proper way in the near future.

I will start with the text from the Visual NDepend website:

NDepend is a tool that simplifies managing a complex .NET code base. Architects and developers can analyze code structure, specify design rules, plan massive refactoring, do effective code reviews and master evolution by comparing different versions of the code.

The result is better communication, improved quality, easier maintenance and faster development.

Also, from the website, here are the list of metrics NDepend can generate for you:

  • 12 metrics on application:
    NbLinesOfCode, NbLinesOfComment, PercentageComment, NbILInstructions, NbAssemblies, NbNamespaces, NbTypes, NbMethods, NbFields, PercentageCoverage, NbLinesOfCodeCovered, NbLinesOfCodeNotCovered
  • 18 metrics on assemblies:
    NbLinesOfCode, NbLinesOfComment, PercentageComment, NbILInstructions, NbNamespaces, NbTypes, NbMethods, NbFields, Assembly level, Afferent coupling (Ca), Efferent coupling (Ce), Relational Cohesion(H), Instability (I), Abstractness (A), Distance from main sequence (D), PercentageCoverage, NbLinesOfCodeCovered, NbLinesOfCodeNotCovered
  • 13 metrics on namespaces:
    NbLinesOfCode, NbLinesOfComment, PercentageComment, NbILInstructions, NbTypes, NbMethods, NbFields, Namespace level, Afferent coupling at namespace level (NamespaceCa), Efferent coupling at namespace level (NamespaceCe), PercentageCoverage, NbLinesOfCodeCovered, NbLinesOfCodeNotCovered
  • 22 metrics on types:
    NbLinesOfCode, NbLinesOfComment, PercentageComment, NbILInstructions, NbMethods, NbFields, NbInterfacesImplemented, Type level, Type rank, Afferent coupling at type level (TypeCa), Efferent coupling at type level (TypeCe), Lack of Cohesion Of Methods (LCOM), Lack of Cohesion Of Methods Henderson-Sellers (LCOM HS), Code Source Cyclomatic Complexity, IL Cyclomatic Complexity (ILCC), Size of instance, Association Between Class (ABC) Number of Children (NOC), Depth of Inheritance Tree (DIT), PercentageCoverage, NbLinesOfCodeCovered, NbLinesOfCodeNotCovered
  • 19 metrics on methods:
    NbLinesOfCode, NbLinesOfComment, PercentageComment, NbILInstructions, Method level, Method rank, Afferent coupling at method level (MethodCa), Efferent coupling at method level (MethodCe), Code Source Cyclomatic Complexity, IL Cyclomatic Complexity (ILCC), IL Nesting Depth, NbParameters, NbVariables, NbOverloads, PercentageCoverage, NbLinesOfCodeCovered, NbLinesOfCodeNotCovered, PercentageBranchCoverage
  • 2 metrics on fields:
    Size of instance, Afferent coupling at field level (FieldCa)

    Now, what I did was start with a small project I have and run the tool to see what I could get with the default settings. The end result was stunning. Once you select the solution to work with, you get the following screen that shows all the projects in the solution and all the libraries it will analyze:

    image

    This is the analysis it will perform (which is of course customizable):

    image

    And the reporting options:

    image

    After running the analysis we get several results, for example:

    Application Metrics

    • Number of IL instructions: 13081
    • Number of lines of code: 1952
    • Number of lines of comment: 1184
    • Percentage comment: 37
    • Number of assemblies: 7
    • Number of classes: 58
    • Number of types: 60
    • Number of abstract classes: 0
    • Number of interfaces: 0
    • Number of value types: 0
    • Number of exception classes: 0
    • Number of attribute classes: 0
    • Number of delegate classes: 4
    • Number of enumerations classes: 2
    • Number of generic type definitions: 0
    • Number of generic method definitions: 0
    • Percentage of public types: 98.33%
    • Percentage of public methods: 72.07%
    • Percentage of classes with at least one public field: 0%

    The numbers are interesting, but up to this point too general. So following with the results report we get more information:

  • image

    The following view is kind of weird, but it shows graphically the size of the assemblies with its methods:

    image

    Also, the dependencies of the assemblies (in large projects this view is very important):

    image

    image

    Assemblies build order

    1. CEO.PublicSite.DataEntities
    2. CEO.PublicSite.DataAccess
    3. CEO.PublicSite.BusinessLogic
    4. CEO.PublicSite.BusinessFacade
    5. CEO.PublicSite.WebControls
    6. CEO.PublicSite.Web
    7. CEO.PublicSite.Utilities

    NDepend information and warnings

    07/04/2009 21:46:04 Begin analysis with NDepend v2.12.1.3123

    07/04/2009 21:46:04 Retrieve dependencies of your application.

    Don’t load
    a previous analysis to compare with.

    Assemblies loaded from {C:\Windows\Microsoft.NET\Framework\v2.0.50727} mscorlib.dll v2.0.0.0 System.Data.dll v2.0.0.0 System.Configuration.dll v2.0.0.0 System.Xml.dll v2.0.0.0 System.dll v2.0.0.0 System.Web.dll v2.0.0.0

    Assemblies loaded from {C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5} System.Web.Extensions.dll v3.5.0.0

    Assemblies loaded from {C:\Users\jrguay\Documents\Visual Studio 2008\Websites\CEO.PublicSite\CEO.PublicSite.Web\bin} CEO.PublicSite.BusinessFacade.dll v1.0.0.0 CEO.PublicSite.BusinessLogic.dll v1.0.0.0 CEO.PublicSite.Web.dll v1.0.0.0 CEO.PublicSite.DataAccess.dll v1.0.0.0 CEO.PublicSite.Utilities.dll v1.0.0.0 CEO.PublicSite.WebControls.dll v1.0.0.0 CEO.PublicSite.DataEntities.dll v1.0.0.0 Telerik.Web.UI.dll v2009.1.527.35

    71 source files parsed ; all source files found ; all source files in-sync with PDB

    0 CQL constraint has been extracted from code.

    No dependency cycle detected in assemblies referencement graph.

    07/04/2009 21:46:12 Analyse dependencies of your application.

    07/04/2009 21:46:13 Building the report (standard).

    WARNING: Assembly {CEO.PublicSite.Utilities} doesn’t contain any type.

    WARNING: No application or tier assembly found in directory {C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0}

    WARNING: No application or tier assembly found in directory {C:\Users\jrguay\Documents\Visual Studio 2008\Websites\CEO.PublicSite\CEO.PublicSite.BusinessFacade\bin\Debug}

    WARNING: No application or tier assembly found in directory {C:\Users\jrguay\Documents\Visual Studio 2008\Websites\CEO.PublicSite\CEO.PublicSite.BusinessLogic\bin\Debug}

    WARNING: No application or tier assembly found in directory {C:\Users\jrguay\Documents\Visual Studio 2008\Websites\CEO.PublicSite\CEO.PublicSite.DataEntities\bin\Debug}

    WARNING: No application or tier assembly found in directory {C:\Users\jrguay\Documents\Visual Studio 2008\Websites\CEO.PublicSite\CEO.PublicSite.DataAccess\bin\Debug}

    WARNING: No application or tier assembly found in directory {C:\Users\jrguay\Documents\Visual Studio 2008\Websites\CEO.PublicSite\CEO.PublicSite.Utilities\bin\Debug}

    WARNING: No application or tier assembly found in directory {C:\Users\jrguay\Documents\Visual Studio 2008\Websites\CEO.PublicSite\CEO.PublicSite.WebControls\bin\Debug}

     

    The result of the CQL Queries and constraints are quite large so I’ll include only one:

    WARNING: The following CQL constraint is not satisfied. 10 methods on 895 tested match the condition. –> Group {Code Quality}

    // <Name>Quick summary of methods to refactor</Name>

    WARN IF Count > 0 IN SELECT TOP 10 METHODS /*OUT OF "YourGeneratedCode" */ WHERE 

                                              
    // Metrics' definitions
         (  NbLinesOfCode > 30 OR              // http://www.ndepend.com/Metrics.aspx#NbLinesOfCode
            NbILInstructions > 200 OR          // http://www.ndepend.com/Metrics.aspx#NbILInstructions
            CyclomaticComplexity > 20 OR       // http://www.ndepend.com/Metrics.aspx#CC
            ILCyclomaticComplexity > 50 OR     // http://www.ndepend.com/Metrics.aspx#ILCC
            ILNestingDepth > 4 OR              // http://www.ndepend.com/Metrics.aspx#ILNestingDepth
            NbParameters > 5 OR                // http://www.ndepend.com/Metrics.aspx#NbParameters
            NbVariables > 8 OR                 // http://www.ndepend.com/Metrics.aspx#NbVariables
            NbOverloads > 6 )                  // http://www.ndepend.com/Metrics.aspx#NbOverloads
         AND 

        
    // Here are some ways to avoid taking account of generated methods.
         !( NameIs "InitializeComponent()" OR
           
    // NDepend.CQL.GeneratedAttribute is defined in the redistributable assembly
    //
    $NDependInstallDir$\Lib\NDepend.CQL.dll
            // You can define your own attribute to mark "Generated".
            HasAttribute "OPTIONAL:NDepend.CQL.GeneratedAttribute")

    And lastly in the report, some Type metrics:

    image

     

    Conclusions

    • The results are quite impressive. The tool can give you a lot of metrics in different levels of the solution.
    • The information about assemblies metrics can give you a very detailed idea in how the assembly is built, how big is it, how are the classes and methods constructed, how they are related to other assemblies and how the types are related to other types within/outside the assembly, and more.
    • One of the most important views is the assembly dependencies, it tells you how each assembly is related to other assemblies by showing for every assembly which assemblies it depends on and which assemblies are referenced by.
    • The CQL queries gives you information about the quality of the code based on metrics definitions. (this definitions can be customized).
    • The type metrics provide detailed information about the types in the assemblies at different levels such as lines of code, lines of IL code, relation with other types, etc.
    • This first review shows me a lot of power in the analysis and reporting capabilities of Visual NDepend (not to mention I didn’t customize any of the default settings).

    I will continue to use the tool and write a second review of the integration with Visual Studio.

    Thanks.


    Leave a Reply

    Your email address will not be published. Required fields are marked *