Wednesday, September 8, 2010

Fluent Validation - Introduction

I have been using the Fluent Validation library for a few years and wanted to share some of the tricks I have learned. This will be broken into a series of posts that will gradually introduce more complex functionality and examples.

So what is “fluent validation”? From their website:

A small validation library for .NET that uses a fluent interface and lambda expressions for building validation rules for your business objects.

And it does this very well. To get started, download the latest version (the examples here are using the 1.3 version).

In this post, I am just going to show you the mechanics of creating a validator class and how to use it. For this example, we will have two classes, Employee and EmployeeValidator.

public class Employee
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}

public class EmployeeValidator : AbstractValidator<Employee>
{
public EmployeeValidator()
{
RuleFor(x => x.FirstName)
.NotEmpty()
.WithMessage("First name is required.");

RuleFor(x => x.LastName)
.NotEmpty()
.WithMessage("Last name is required.");
}
}

Our Employee class is pretty basic so let’s spend some time examining our validator class. First, notice that it extends the AbstractValidator base class from the FluentValidator library (you may need to add a reference to the FluentValidation.dll you downloaded earlier). Next, we define a set of business rules in the constructor. In this case our business rules are:

  1. First name cannot be null or empty
  2. Last name cannot be null or empty

To define a rule, we use the RuleFor method that uses a Lambda expression to define what property the rule will apply to. There are several built-in validators for strings, numbers, predicates, RegEx, even an email validator (you can also create custom validators which I will get to later in the series).

Now that we have a validator, the usage is quite simple. We pass our object to our validator through the Validate method and receive a ValidationResult:

class Program
{
static void Main(string[] args)
{
Employee employee = new Employee();
IValidator validator = new EmployeeValidator();

ValidationResult result = validator.Validate(employee);
ShowResult(result);

employee.FirstName = "Jack";
employee.LastName = "Handy";
result = validator.Validate(employee);
ShowResult(result);
}

static void ShowResult(ValidationResult result)
{
if (result.IsValid)
{
Console.WriteLine("Employee is valid.");
}
else
{
Console.WriteLine("Employee is NOT valid.");
List<ValidationFailure> errors = new List<ValidationFailure>(result.Errors);
errors.ForEach(x => Console.WriteLine(x.ErrorMessage));
}
}
}

According to our validation rules, when we instantiate a new Employee object, it will be invalid because the FirstName and LastName properties will be empty. The first time we call ShowResult, our employee object will be invalid. We iterate over the Errors collection of the ValidationResult object and write the error messages to the console window. The second time we call ShowResult, the FirstName and LastName properties have been set, and our object is valid.

Running the above code will result in:

image


Hopefully this very simple example gives you an idea of how this might be used in your domain. Next time we will take a TDD approach to writing validation rules and look at some more complex examples.

1 comment: