In previous article, we have seen how RuleSets can be used to trigger different validations in different contexts. In this article, we are going to discuss about another pattern which can be used for same purpose, including validators.
Before we begin !
I have been writing about the fluent validation library and below is the list of all the articles that I have published recently.
- Adding Fluent Validation in ASP .NET Core Web APIs
- ASP .NET Core API – Placeholders in Fluent Validation Messages
- ASP .NET Core API – Fluent Validations – Customizing Messages
- ASP .NET Core API – Fluent Validations – Collections
- ASP .NET Core API – Fluent Validators and Dependency Injection
- ASP .NET Core API – Fluent Validations – Cascade Behaviour
- Demo – Inheritance Validation using Fluent Validations
- ASP .NET Core API – Conditions in Fluent Validations
- ASP .NET Core API – Fluent Validations Based On Database Data
- ASP .NET Core API – Fluent Validation RuleSets
Quick Overview of RuleSet
We have discussed about the concept of RuleSet. It basically allows to group the validation rules together. Then while triggering the validation, we can specify which RuleSets should be used for validation. This technique can be useful when there is a same model, which is being used for multiple endpoints and every endpoint has different validation needs.
For code example, I would suggest to refer the previous article.
Is there any issue with RuleSet ?
Practically, RuleSets can be handy for grouping validation rules. The only problem that one may see in this approach is – all the validations are being grouped inside the same validator class, making the class bigger.
What is the alternative approach ?
The alternative approach is to group the rules in multiple Validator classes. The type which is to be validated would be same in all those validator types. Each class will have some rules, either specific to a property or specific set of business validations, which can be bundled together. Then we can compose the required validations by using some (or all ) of these validators.
Example
I have used the same code example that we used in the previous blog post, only the approach to solve the same problem is different. There are 7 validators, each of them targeting to the same type, Student
.
- StudentWithIdValidator, to check that
Id
should be greater than zero - StudentWithoutIdValidator, to check that
Id
should be equal to zero - StudentWithVersionValidator, to check that
Version
should be greater than zero - StudentWithoutVersionValidator, to check that
Version
should be equal to zero - StudentNameValidator, to apply validations to Name property
- AddStudentValidator, which contains validators combined for
AddStudent
endpoint. This validator should be triggered from the add endpoint. - UpdateStudentValidator, which contains validators combined together for
UpdateStudent
endpoint. This validator should be triggered from the update endpoint.
In the StudentController
, we now need to use two validators, add endpoint should use the AddStudentValidator
and update endpoint should use UpdateStudentValidator
.
I hope this article gives you fair idea about how a set of business valdiation can be broken into smaller pieces of dedicated validators. And then from them, we can compose the endpoint specific validators.
I hope you find this information helpful. Let me know your thoughts.