How to Avoid Code Smells - A NDepend Tutorial

Written by ssukhpinder | Published 2023/03/01
Tech Story Tags: coding | code-review | ndepend | csharp | dotnet | dotnet-core | clean-code | code-quality | web-monetization

TLDRDevelopers can evaluate and visualize the codebase using the robust static analysis tool NDepend. It aids programmers in understanding the quality and maintainability of the code. Refactoring a type with too many methods involves splitting the type into smaller, more manageable types that each have a single responsibility.via the TL;DR App


Learning Objectives

  • Avoiding Common Code Smells in C# using NDepend

Prerequisites

  • First, Install the latest Visual Studio here.

  • Download NDepend Trail Edition here.

  • Unzip the download, and install the VS extension.

Official Documentation for more info

.Net Code Analysis - NDepend Part-1

Getting Started

.NET developers can evaluate and visualize the codebase using the robust static analysis tool NDepend. It aids programmers in understanding the quality and maintainability of the code, spotting bugs and other possible problems, and monitoring code metrics.

Refactoring Types with Too Many Methods

Refactoring a type with too many methods involves splitting the type into smaller, more manageable types that each has a single responsibility to make the code easier to understand and maintain and reduce the risk of introducing bugs in the future.

Code Example

Suppose a class called “Customer” has the following methods:

public class Customer
{
    public void AddOrder(Order order) { ... }
    public void RemoveOrder(Order order) { ... }
    public void UpdateOrder(Order order) { ... }
    public void GetOrders() { ... }
    public void GetCustomerDetails() { ... }
    public void GetCustomerHistory() { ... }
    // ... more than 20 methods
}

NDepend Error

Refactored Solution

The class has too many methods and violates the Single Responsibility Principle. To refactor the class, split it into three separate classes.

  • CustomerOrderService

  • CustomerDetailsService

  • CustomerHistoryService

Each class will have a single responsibility, making the code easier to understand and maintain, as shown below in the refactored solution.

public class CustomerOrderService
{
    public void AddOrder(Customer customer, Order order) { ... }
    public void RemoveOrder(Customer customer, Order order) { ... }
    public void UpdateOrder(Customer customer, Order order) { ... }
    public void GetOrders(Customer customer) { ... }
}

public class CustomerDetailsService
{
    public void GetCustomerDetails(Customer customer) { ... }
}

public class CustomerHistoryService
{
    public void GetCustomerHistory(Customer customer) { ... }
}

// Refactor remaining methods as well

Refactoring the “Customer” class into these three smaller classes improved the code’s maintainability and reduced the risk of introducing bugs in the future.

Avoiding Non-Readonly Static Fields

To avoid non-read-only static fields, mark all static fields as read-only unless they need to be modified. Keeping a field read-only ensures that it cannot be changed after initializing, making it thread-safe and easier to maintain.

Static fields in C# are used to share data across instances of a class. Once initialized, it maintains value throughout the lifetime of the application domain.

Code Example

public class MyClass
{
    public static int Count = 0;
    
    public void IncrementCount()
    {
        Count++;
    }
}

If numerous instances of the MyClass class are created, and if all can edit the Count field, then it may result in unexpected behavior.

NDepend Error

It is advised to specify static fields as read-only wherever possible to prevent these problems. When a static field is designated as read-only, either in the declaration, its value can only be changed once. It lowers the possibility of subtle problems and makes it simpler to reason about the program's state.

Refactored Solution

public class MyClass
{
    public static readonly int Count = 0;
    
    static MyClass()
    {
        Count = 10;
    }
}

Don’t Assign Static Fields From Instance Methods.

All class instances share the value passed to a static field from an instance method. If numerous class instances edit the static field simultaneously, this could result in unexpected behavior. Think about the following code for instance:

Code Example

public class MyClass
{
    public static int Count = 0;

    public void IncrementCount()
    {
        Count++;
    }
}

NDepend Error

Using NDepend to identify the issues in the codebase and refactoring is to avoid them. Moreover, it can improve the quality and maintainability of the code.

Refactored Solution

public class MyClass
{
    public static int Count = 0;

    static MyClass()
    {
        IncrementStaticCount();
    }
    private static void IncrementStaticCount()
    {
        Count++;
    }
}

Finally, I added a private static method called IncrementStaticCount to this refactored code that increases the value of the Count static field. The IncrementCount method now invokes the IncrementStaticCount method as an instance method.


Check out the rule explorer for more information

NDepend Rules Explorer


Thank you for reading, and I hope you liked the article. Please provide your feedback in the comment section.

Stay tuned for more posts on Code Analysis with NDepend.

Follow me on

C# Publication, LinkedIn, Instagram, Twitter, Dev.to

Similar Articles

Run SonarQube Locally — .Net
How to run SonarQube locally for .Net solutionsmedium.com

Enforce code cleanup on build — .Net
Create code cleanup profiles and run on the build-in Visual Studio.medium.com

GitHub SonarQube workflow — .Net
How to set up GitHub SonarQube workflow on pull request for .Net repositoriesmedium.com


Also published here


Written by ssukhpinder | I'm Sukhpinder Singh, a passionate self-taught .Net developer from India.
Published by HackerNoon on 2023/03/01