Over a few years, I have have written a few validation classes and have always wonder what people thinks is the best way of handling them.
I’ve seen and done each of the following and am curious to your know opinions and why.
Scenario 1, Message Counting
class ValidationClass1
{
public List<string> ValidationMessage { get; set; }
public void Validate(x)
{
// pseudo-code
if (!rule_logic1)
{
ValidationMessage.Add("Error in logic 1");
}
if (!rule_logic2)
{
ValidationMessage.Add("Error in logic 2");
}
}
}
Scenario 2, Returning an Object or Tuple
class ValidationClass
{
public Tuple<bool, List<string>> Validate(x)
{
List<string> ValidationMessage = new List<string>();
bool passed = true;
// pseudo-code
if (!rule_logic1)
{
ValidationMessage.Add("Error in logic 1");
passed = false;
}
if (!rule_logic2)
{
ValidationMessage.Add("Error in logic 2");
passed = false;
}
return new Tuple<bool, List<string>>(passed, ValidationMessage);
}
}
In Scenario 1, the ValidationMessage list could be the return type as well. Regardless, calling code would have to check the count property of the list to see if the data passed or not. If it was only a singular rule, the returning string length would need to be checked via string.IsNullOrEmpty(x).
In Scenario 2, a custom object or tuple would be the return type so that the calling code would have to have knowledge of the returning code and evaluate a boolean property to see if it passed and then the validation messages.
So, in your opinion, which way do you prefer or if you have a different preference, I’d be curious to hear that as well.
Thanks
I’ve used a variant of Martin Fowler’s Notification Pattern to handle validation and associated validation error messages.
Here is the specific class that might address your “Boolean or Count” question:
His pattern uses more granular members to indicate whether general validation failure has occurred (‘HasErrors’ which returns a boolean based on ‘Errors’ collection count) and what specifically has failed (‘Errors’ collection from which you can derive a count) The actual ‘Validate’ code that runs the validation is a separate method altogether (found on the business/domain object that requires validation).
The pattern might be a bit out to date (including my own previous implementation) but it does expose you to some alternatives and can give you some ideas to build on.