Compartir a través de


Walkthrough: Adding Custom Validation to a Domain Model

As the author of a domain-specific language, you can add custom validation to your domain model. Users of your domain-specific language can validate the models that they create from that language and display the results. For more information, see Validation Overview for Domain-Specific Languages.

In this walkthrough, you add custom validation methods to a domain model. For information about how to add standard validation, see How to: Add Validation to a Domain Model or Walkthrough: Adding Validation to a Domain Model.

Prerequisites

To complete this walkthrough, you must:

Create a Domain-Specific Language

The first step is to create a domain-specific language to which you will add custom validation. You will create the domain-specific language by using the Class Diagrams solution template.

To create a domain-specific language

  1. On the File menu, point to New, and then click Project.

    The New Project dialog box appears.

  2. Under Project types, expand the Other Project Types node, and click Extensibility.

  3. Under Templates, click Domain-Specific Language Designer.

    Important Note:

    Do not click the Domain Specific Language Setup template.

  4. In Name, type CustomValidation, and click OK.

    The Domain-Specific Language Designer Wizard appears.

  5. On the Select Domain-Specific Language Options page, click Class Diagrams.

  6. In What do you want to name your domain-specific language, leave the default value, CustomValidation, and click Next.

  7. On the Define New Model File Type page, under What extension should model files use?, type custv, and click Next.

  8. On the Specify Product Details page, under What is the name of the company that the product belongs to?, type Fabrikam or your company name.

    The names that are specified on this page are automatically composed to create the namespace shown at the bottom. This should comply with the typical namespace rules.

  9. Verify that the namespace is valid, and then click Next.

  10. On the Select Strong Name Signing Method page, leave the default setting of Create a strong name key file, and click Next.

  11. On the Review Details of the Domain-Specific Language Solution page, review the settings that you have specified.

  12. If changes are necessary, click Previous as necessary to make corrections.

  13. When you are satisfied with the settings, click Finish.

    The system creates a solution called CustomValidation based on the name that you specified and the Class Diagram solution template. The solution has two projects, which are named Dsl and DslPackage.

    Nota

    When you create a project, the system automatically generates the default text templates. When you generate a text template, you will see a message warning you not to run text templates from untrusted sources. If you do not want this message to appear again, select the Do not show this message again check box, and click OK. Otherwise, click OK.

Enabling the Validation Framework

Before you can add custom validation, you must set the custom validation global switch in the language definition.

To enable the validation framework

  1. In Solution Explorer, open DslDefinition.dsl in the Dsl project.

  2. In DSL Explorer, expand the Editor node, and then click Validation.

    If DSL Explorer is not appearing, open the View menu, point to Other Windows, and click DSL Explorer.

  3. In the Properties window, set the Uses Custom property to True.

    If the Properties window does not appear, press F4.

  4. Save DslDefinition.dsl.

Create Custom Validation Method in Partial Class for ModelClass

To define your custom validation constraints, you will add a custom validation method to a partial class for ModelClass.

To add the custom validation method to the ModelClass class

  1. In Solution Explorer, right-click the Dsl project, point to Add, and click New Folder.

  2. Name the folder Custom.

  3. Right-click the Custom folder, point to Add, and click New Item.

  4. In the Add New Item dialog box, in the Templates list, click Code File.

  5. In the Name box, type CustValidModelClass.cs, and click Add.

  6. Copy the following code to the CustValidModelClass.cs file to create a partial class for the ModelClass class.

    using Microsoft.VisualStudio.Modeling;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.Modeling.Validation;
    using System.Windows.Forms;
    using System;
    
    namespace Fabrikam.CustomValidation
    {
        [ValidationState(ValidationState.Enabled)]
        public partial class ModelClass
        {
            [ValidationMethod(CustomCategory = "CircularInheritanceCheck")]
            private void ValidateCircularInheritance(ValidationContext context)
            {
                string circularPath = this.Name;
                // List<ModelClass> visitedClass 
                ModelClass baseClass = this.Superclass;
                while (baseClass != null)
                {
                    circularPath += " -> " + baseClass.Name;
    
                    if (baseClass == this)
                    {
                        context.LogError( string.Format( "ModelClass {0} has a circular inheritance relationship: {1}", this.Name, circularPath),
                                          "Cir001", this);
                        break;
                    }
                    baseClass = baseClass.Superclass;
                }
            }
        }
    }
    

Create Custom Validation Method in Partial Class for CustomValidationExplorer

In the DslPackage project, you will create a custom code file that subscribes to the SubscribeToImsEvent method event.

To add the custom validation method to the CustomValidationExplorer class

  1. In Solution Explorer, right-click the DslPackage project, point to Add, and then click New Folder.

  2. Name the folder Custom.

  3. Right-click the Custom folder, point to Add, and click New Item.

  4. In the Add New Item dialog box, in the Templates list, click Code File.

  5. In the Name box, type CustValidExplorer.cs, and click Add.

  6. Copy the following code to the CustValidExplorer.cs file to create a partial class for the CustomValidationExplorer class.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.VisualStudio.Modeling.Shell;
    using Microsoft.VisualStudio.Modeling;
    
    namespace Fabrikam.CustomValidation.DslPackage
    {
        internal partial class CustomValidationExplorer
        {
            /// <summary>
            /// Subscribe IMS events
            /// </summary>
            /// <param name="newStore">Store</param>
            protected override void SubscribeToImsEvent(Store newStore)
            {
                // call base class first.
                base.SubscribeToImsEvent(newStore);
    
                // subscribe to the IMS event ended event.
                newStore.EventManagerDirectory.ElementEventsEnded.Add(new EventHandler<ElementEventsEndedEventArgs>(IMSEventEndedHandler));
            }
            protected override void UnsubscribeToImsEvent(Store oldStore)
            {
                base.UnsubscribeToImsEvent(oldStore);
    
                oldStore.EventManagerDirectory.ElementEventsEnded.Remove(new EventHandler<ElementEventsEndedEventArgs>(IMSEventEndedHandler));
            }
    
            /// <summary>
            /// private event handler when IMS event is ended.
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void IMSEventEndedHandler(Object sender, ElementEventsEndedEventArgs e)
            {
                // When IMS event has finished, we will invoke the custom validation to make sure there's no circular inheritance 
                // among ModeClass.
                CustomValidationDocData docData = this.ModelingDocData as CustomValidationDocData;
                docData.ValidationController.ValidateCustom(docData.Store, "CircularInheritanceCheck");
            }
        }
    }
    

Test the Constraint

Rebuild your project to test the validation code in the generated designer.

To test the constraint

  1. Regenerate the code for the solution by clicking Transform All Templates on the Solution Explorer toolbar.

    Nota

    You might see a message warning you not to run text templates from untrusted sources. If you do not want this message to appear again, select the Do not show this message again check box, and click OK. Otherwise, click OK.

  2. On the Build menu, click Rebuild Solution.

  3. On the Debug menu, click Start Debugging, or press F5.

  4. Open Test.custv.

  5. Drag a Class item from the Class Diagrams tab of the Toolbox to the diagram surface of the generated designer.

    This action creates a class named ModelClass1.

  6. Drag a second Class item from the Class Diagrams tab of the Toolbox to the diagram surface of the generated designer.

    This action creates a class named ModelClass2.

  7. Click the Inheritance item in the Toolbox, and then drag the cursor between ModelClass1 and ModelClass2 in the diagram to create a link.

  8. Click the Inheritance item in the Toolbox again, and then drag the cursor between ModelClass2 and ModelClass1 on the diagram to form a circular inheritance among the classes.

    The validation error about circular inheritance appears in the Error List window.

See Also

Concepts

Validation Overview for Domain-Specific Languages

How to: Add Validation to a Domain Model

Family Tree Sample

User Interface Process Sample

Class Diagram Sample

Domain-Specific Language Tools Glossary