Model Validation Extensions

Retired Content

The Web Service Software Factory is now maintained by the community and can be found on the Service Factory site.

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies.
This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Retired: November 2011

The last significant extension introduced by the Service Factory is a validation mechanism that allows you to externally, in respect to a DSL, specify and implement the model validation rules. The mechanism “hooks into” the DSL validation framework in the following way:

The validation starts when the user clicks Validate or Validate all on the context menu of a model. This invokes the DSL framework's DslCommandSet object.

The DSL DslCommandSet class (the class is generated by the DSL tool with the model name prefix) now includes custom OnMenuValidate and OnMenuValidateModel methods. For an example, see the ServiceContractDslCommandSet.cs file in the ServiceContractDslPackage project; it is in the CustomCode\CommandSet folder.

The preceding methods call the FullDepthElementWalker, which creates a list of model elements reachable from the selected element. The FullDepthElementWalker class is in the Microsoft.Practices.Modeling.CodeGeneration project in the Libraries solution folder.

After the walker returns all elements that must be validated, the OnMenuValidate and OnMenuValidateModel call the DSL framework's ValidationController with that list.

For a model element to be validated by the extended DSL framework, it has to implement two methods from the IValidatableElement interface: OnValidate and ContinueValidation. The methods are boilerplate code, as shown here, and call the ValidationEngine.

[TypeDescriptionProvider(typeof(ExtendedTypeDescriptionProvider))]
[ValidationState(ValidationState.Enabled)]
public partial class Fault : IExtensibleObject, IValidatableElement
{
#region IExtensibleObject Members
… 
#endregion

#region Validation support

[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());
}

#endregion
}

The ValidationEngine class is located inside the Microsoft.Practices.Modeling.CodeGeneration project in the Libraries solution folder. It performs the model element validation using the Enterprise Library Validation Application Block and logs the validation errors.

What validation should be performed for each type of element in a model, is defined in the Enterprise Library configuration file. The file is named Ruleset.config and is located in the Service Factory Guidance Package. After building this project, the Ruleset.config is copied to the project's output directory and can be consumed by the Validation Framework. The following example is a fragment of the configuration file and includes three validation rules (called validators) for the ServiceContract model element; two for the property Namespce and one for the property Operations.

<ruleset name="Menu">
   <properties>
       <property name="Namespace">
         <validator type="Microsoft.Practices.ServiceFactory.Validation.UriValidator, Microsoft.Practices.ServiceFactory.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
messageTemplate="The ServiceContract Namespace property is incorrect."
name="Service.Namespace property validator"
/>
       <validator type="Microsoft.Practices.ServiceFactory.Validation.NonEmptyNamespaceValidator, Microsoft.Practices.ServiceFactory.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
messageTemplate="The ServiceContract '{0}' Namespace property is empty."
name="ServiceContract.Namespace Validator"
/>
    </property>
       <property name="Operations">
          <validator type="Microsoft.Practices.ServiceFactory.Validation.NotEmptyOperationCollectionValidator, Microsoft.Practices.ServiceFactory.Validation, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
messageTemplate="ServiceContract does not have Operations."
name="Operation.ServiceContract not null validator"
/>
        </property>
    </properties>
</ruleset>

Each rule identifies the validator that implements the rule. The Service Factory comes with a large set of validator classes. They are all in the Microsoft.Practices.ServiceFactory.Validation project in the Libraries solution folder. One validator, the CrossModelReferenceValidator, is really a part of the validation mechanism and plays a specific role in this mechanism:

  • It resolves the cross model reference property it is applied to.
  • It sees whether the target element can be validated—it implements IValidatableElement—and if it should be validated, the validator calls the validation engine and passes that model element to it to continue the validation.

The final result of using this validation mechanism is that Service Factory users can modify how the models are validated by changing the provided rules and validators or adding their own ones. All this can be done without opening, modifying, rebuilding, and re-deploying the DSLs by following these two steps:

  1. Create a validator class and put it in the Microsoft.Practices.EnterpriseLibrary.Validation project with the other validators.
  2. Add entries to the Rules.config file to define what property of what model element class the validator should be applied.