Service Factory model validation
Thursday, November 8, 2007 – 10:32 AMNow Service Factory: Modeling Edition has finally shipped I felt obligated to write some stuff about it. As Dev Lead I didn’t actually get to write a lot of code but one place I did get my hands grubby was the validation framework.
In the process of putting together our presentation for the p&p Summit we noticed that the validation framework didn’t have a diagram. I’ve taken it upon myself to create one and talk a bit about how the validation framework actually works. The documentation’s “Service Factory Architecture” topic covers most of this but the are some gaps I thought I’d clear up.
When you validate a model element in one of the service factory designers we use a custom element walker – FullDepthElementWalker – to return a list of the element and all its dependencies. This list is then passed to the validation controller.
To implement standard DSL validation the Fault class provides an method decorated with the ValidationMethod attribute. The the DSL validation controller uses this to request that an object validates itself. For example:
[ValidationState(ValidationState.Enabled)]
public partial class Fault : IExtensibleObject, IValidatableElement
{
[ValidationMethod(ValidationCategories.Menu |
ValidationCategories.Open | ValidationCategories.Save)]
private void OnValidate(ValidationContext context)
{
ValidationEngine.Validate(ValidationElementState.FirstElement,
context, this, context.Categories.ToString());
} public void ContinueValidation(ValidationContext context)
{
ValidationEngine.Validate(ValidationElementState.LinkedElement,
context, this, context.Categories.ToString());
}
}
In addition Service Factory supports cross model validation via the CrossModelReferenceValidator. The CrossModelReferenceValidator will resolve a cross model reference using the DIS PowerToy and then continue validation on the referenced model element if it implements the IValidatableElement.
Looking at the code above the only difference between these two cases is that the first parameter to Validate() is different. The ValidationEngine tracks which model elements have been validated so that elements do not get validated twice resulting in duplicated error messages. It does this by tracking validated elements using the ValidationMemory. All the ValidationElementState flag does is cause the memory to be reset in the FirstElement case. In the LinkedElement case the memory remains so if validation “hops” from one model to another the list of previously visited elements is preserved. In either case the validation engine ultimately spins up the EntLib Validator and loads the ruleset configuration and then validates the model element according to its type.
We used this approach as it provides an open, extendable validation framework. Factory users can add new rules to the ruleset file and if need be new validators. Both the ruleset and the validators are dynamically loaded so there’s no need to rebuild the factory in order to extend model validation. The only issue is there is that we only support one ruleset file. The EntLib validation framework doesn’t provide a simple way to merge multiple rulesets. This will cause versioning conflicts if you want to apply multiple new validation rules to your factory.
1 Trackback(s)
Sorry, comments for this entry are closed at this time.