There is only one validation framework that I know well, and that is the “Enterprise Library Validation Application Block” or a summary of VAB. I will answer your questions from the context of VAB.
First question: Can you do a status check (between fields) in a VAB?
Yes, you can. There are several ways to do this. You can choose a self-checking mechanism, as shown below:
[HasSelfValidation] public class Range { public int Min { get; set; } public int Max { get; set; } [SelfValidation] public void ValidateRange(ValidationResults results) { if (this.Max < this.Min) { results.AddResult( new ValidationResult("Max less than min", this, "", "", null)); } } }
I have to say that I personally do not like this type of verification, especially when checking my domain objects, because I like to separate my checks from the verification logic (and keep my domain logic free from links to any verification system), however, they need significantly less code than an alternative that writes its own validation class. Here is an example:
[ConfigurationElementType(typeof(CustomValidatorData))] public sealed class RangeValidator : Validator { public RangeValidator(NameValueCollection attributes) : base(string.Empty, string.Empty) { } protected override string DefaultMessageTemplate { get { throw new NotImplementedException(); } } protected override void DoValidate(object objectToValidate, object currentTarget, string key, ValidationResults results) { Range range = (Range)currentTarget; if (range.Max < range.Min) { this.LogValidationResult(results, "Max less than min", currentTarget, key); } } }
After writing this class, you can include this class in the validation configuration file as follows:
<validation> <type name="Range" defaultRuleset="Default" assemblyName="[Range Assembly]"> <ruleset name="Default"> <validator type="[Namespace].RangeValidator, [Validator Assembly]" name="Range Validator" /> </ruleset> </type> </validation>
The second question: how to perform complex checks with possible database interaction (with VAB).
The examples that I give for the first question are also applicable for this. You can use the same methods: self-checking and a custom validator. Your scenario in which you want to check the value in the database is actually simple, since the reality of your object is not based on its context. You can simply check the state of the object in the database. This becomes more complex when the context in which the object lives becomes important (but this is possible with VAB). Imagine, for example, that you want to write a validation that ensures that each client at a given time has no more than two unsigned orders. This not only means that you need to check the database, but perhaps new orders that have been added or orders are deleted in the same context. This problem is not specific to VAB, you will have the same problems with every structure you choose. I wrote an article that describes the difficulties that we face in these situations (reading and trembling).
Third question: how do you people in the real world deal with this situation?
I am doing these types of validation with VAB in production code. It works great, but VAB is not very easy to learn. However, I love what we can do with VAB, and it will only improve when v5.0 comes out. When you want to learn it, start by reading the ValidationHOL.pdf document, which you can find in Hands-On Labs for download.
Hope this helps.