C#

What are Guard Clauses in .NET

What are Guard Clauses?

A guard in general is to protect against the damage that may happen in the future.

In computer programming, a guard is a boolean expression that must evaluate to true if the program execution is to continue in the branch in question

wikipedia

Failing fast is a good strategy when writing code. It allows us to short-circuit the code execution. Guard clauses are a technique to achieve fast failing.

How to guard a method?

Let’s say we have the following method

bool SendEmail(string emailAddress)
{
    return _repo.SendEmail(emailAddress);
}

Given an email address, the SendEmail method sends an email to the user.

But, what if we pass a NULL or EMPTY value to our method. We can raise an exception if the input is not valid or null or blank etc (not validating the email address at it may distract the intent)

Here is our revised code

bool SendEmail(string emailAddress) 
{
 if (string.IsNullOrWhiteSpace(emailAddress)) {
  throw new ArgumentNullException(nameof(emailAddress));
 }
 
 return _repo.SendEmail(emailAddress);
}

Throwing an ArgumentNullException when the email address is null or whitespace is a guard here.

Great. This is all looking good.

What if we want to check the inputs for null or check if the list has values across the project and raise appropriate exceptions?

Well, we can write these checks all over the project but this leads to code duplication all over the place. Let’s see what libraries we have for guard clauses.

Available Guard Clauses Libraries

I found these 3 libraries which had more downloads on nuget.com

Library NameLast UpdatedSupported Frameworks
Ardalis.GuardClauses4 months ago .NET 6, .NET Standard 2.0, .NET Framework 4.5.1
Dawn.Guard 3/31/2020 .NET Standard 1.0
Guard.Net9 months ago .NET 5.0

For this article, I’ll make use of Ardalis.GuardClauses library as it is supporting latest frameworks.

Refactoring our method using Ardalis.GuardClauses

Let’s try to refactor our SendEmail method with Guard.Against.NullOrWhiteSpace method.

bool SendEmail(string emailAddress) 
{
 Guard.Against.NullOrWhiteSpace(emailAddress, nameof(emailAddress));
 return _repo.SendEmail(emailAddress);
}

That’s it! We went from this

if (string.IsNullOrWhitespace(emailAddress)) {
    throw new ArgumentNullException(nameof(emailAddress));
}

to this

Guard.Against.NullOrWhiteSpace(emailAddress, nameof(emailAddress));

Looks good right.

Most used guard in my opinion: Guard.Against.Null

When supplying dependencies through class constructors we usually perform ?? (null-coalescing-operator) against the parameters to avoid throwing null reference exceptions. We do something like this.

public class UserManager
    {
        private readonly IUserRepository _userRepo;
        private readonly IDepartmentRepsitory _deptRepo;
        private readonly IEmailService _emailService;
        private readonly ILogger _logger;

        public UserManager(IUserRepository userRepo, IDepartmentRepsitory deptRepo, IEmailService emailService, ILogger logger)
        {
            _userRepo = userRepo ?? throw new ArgumentNullException(nameof(userRepo));
            _deptRepo = deptRepo ?? throw new ArgumentNullException(nameof(deptRepo));
            _emailService = emailService ?? throw new ArgumentNullException(nameof(emailService));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }
    }

With Guard.Against.Null we can transform the above code into this.

public class UserManager
    {
        private readonly IUserRepository _userRepo;
        private readonly IDepartmentRepsitory _deptRepo;
        private readonly IEmailService _emailService;
        private readonly ILogger _logger;

        public UserManager(IUserRepository userRepo, IDepartmentRepsitory deptRepo, IEmailService emailService, ILogger logger)
        {
            _userRepo = Guard.Against.Null(userRepo, nameof(userRepo));
            _deptRepo = Guard.Against.Null(deptRepo, nameof(deptRepo));
            _emailService = Guard.Against.Null(emailService, nameof(emailService));
            _logger = Guard.Against.Null(logger, nameof(logger));
        }
    }

The code is now more concise when compared with null coalescing checks right?

Supported Guard clauses in Ardalis.GuardClauses

  • Guard.Against.Null (throws if input is null)
  • Guard.Against.NullOrEmpty (throws if string, guid or array input is null or empty)
  • Guard.Against.NullOrWhiteSpace (throws if string input is null, empty or whitespace)
  • Guard.Against.OutOfRange (throws if integer/DateTime/enum input is outside a provided range)
  • Guard.Against.EnumOutOfRange (throws if a enum value is outside a provided Enum range)
  • Guard.Against.OutOfSQLDateRange (throws if DateTime input is outside the valid range of SQL Server DateTime values)
  • Guard.Against.Zero (throws if number input is zero)

Do we really need a library for Guard classes?

It depends. The library we used in this article packs a bunch of useful guard methods which we can use on a daily basis. Ex: NullOrWhiteSpace, Zero

But, if we need only a couple of methods from Ardalis.GuardClauses then I think it may not be useful to add it as a dependency to our project.

Let’s say we use only null reference guards in our project, then it’s better we can create a static method and utilize them everywhere.

We can write a static method that does the same thing as Guard.Against.Null

public static class GuardX
{
    public static T ThrowIfNull<T>(T input, string message)
    {
        if (input is null) throw new ArgumentNullException(message);

        return input;
    }
}

And while guarding, we can do this

_userRepo = GuardX.ThrowIfNull(userRepo, nameof(userRepo));

If we have to check if a collection is empty, we can write another static method and use it. Again, its upto you.

References

  1. Ardalis.GuardClauses
  2. Guard – Wikipedia
Disqus Comments Loading...
Share
Published by
Karthik Chintala

Recent Posts

2 Good Tools To Test gRPC Server Applications

In this post, we’ll see how to test gRPC Server applications using different clients. And… Read More

12 months ago

Exploring gRPC project in ASP.NET Core

In this post, we'll create a new gRPC project in ASP.NET Core and see what's… Read More

1 year ago

Run dotnet core projects without opening visual studio

In this blog post, we’ll see how to run dotnet core projects without opening visual… Read More

1 year ago

Programmatically evaluating policies in ASP.NET Core

Programmatically evaluating policies is useful when we want to provide access or hide some data… Read More

1 year ago

Multiple authorization handlers for the same requirement in ASP.NET Core

We saw how we could set up policy-based authorization in our previous article. In this… Read More

1 year ago

Policy-Based Authorization in ASP.NET Core

What is policy-based authorization and how to set up policy-based authorization with handlers and policies… Read More

1 year ago

This website uses cookies.