Skip to content

Reusable Validation

danludwig edited this page Dec 27, 2014 · 5 revisions

Many business rules manifest themselves through user input validation. For example, say you have a system for managing employee salaries. It may be a business rule that you cannot increase an employee's salary by more than 5% every 12 months. How would you enforce this business rule? Whenever the system receives a command to change that salary, you would have an algorithm that reads the salary 12 months ago, along with the new salary amount, and runs some simple math to make sure the command is not violating the rule. If it is, you would reject the command and display a message to the end user.

To me, any business rule that gets manifested as a data input validation falls into one of two categories. First, you have your functional validations, which simply compare the input against a known pattern to achieve a pass or fail result. For example if you have a currency field, you don't want users to be able to enter alphabetic characters into that field. Required field validations fall into this category, as well as regular expression validations. In fact, anything that does not have to reach into a database or other external resource to read information before being able to determine pass or fail falls into this category.

The other category of validations do have to reach into some external resource to read data before they can pass or fail the input. I often refer to these kinds of validations as "verifications". A perfect example of this is a uniqueness validator. When you go to create a new twitter account, you have to choose a username. However you can't pick a username that someone else already has registered, you need your own unique username. To validate this, the system has to check its business data store to see if there are any pre-existing accounts with your chosen username.

ASP.NET has something called "Data Annotations" which they recommend using for validating user input. With these, you can implement business rules by adding compile-time attributes to classes like viewmodels and EF entity classes. While these data annotations attributes are pretty good at the first category of validations, they are horrible at doing data input verification (the second category). The reason is because there is no good, easy way to inject dependencies into data annotations attributes. You can do it using property injection, but not constructor injection.

Remember, Tripod's main API for performing business use cases are queries and commands. Most often, you will only need to perform validation when executing a command (though you may find instances when it is also necessary to validate queries, it is much less common). Wouldn't it be great if we could somehow put some kind of validation mechanism in front of every command, so that each command can be validated before it gets executed? It would be cool. In fact it is cool, because that is exactly what Tripod does.

##The Best Validation Tool Available in .NET

Tripod's Domain assembly tries not to take very many dependencies on external tools, and only does so when it makes good sense. One of the tools that the Domain takes a dependency on is FluentValidation.NET, which is a great tool. It allows you to do any kind of validation you would ever need to, either against a known pattern or against existing data. You can wire it up to your IoC container to enable constructor injection, so your validators are fully unit testable. It also has integration with MVC and WebAPI so that you can reuse command validators to validate input models that come into MVC and WebAPI.