Share via


How to: Create a Custom Constraint on a Setting

How to: Create a Custom Constraint on a Setting

There are different types of constraints you use to control how systems, resources, and endpoints are used. Setting constraints compare setting values to determine when to raise an error. Evaluation of the setting values is done by a manager that is implemented by the creator of the setting constraint. The manager uses C# code to evaluate the setting values and decide when to raise an error. There are standard constraints that evaluate settings, but if a standard constraint does not evaluate a setting the way you want it to, you can create your own setting constraint. For a list of standard constraints, see How to: Create a Constraint on a Relationship.

Constraints can be implemented by a manager. Managers allow you to define the custom behavior of a constraint by implementing the behavior of the constraint in C# code. A manager is defined in an .sdm file (in XML) and then the SDM Manager Generator (SdmG.exe) command line tool is used to create the manager in C#. After the manager is created, you write C# code to implement the constraint behavior.

To Create a Setting Constraint

In this topic you will create a manager that will check whether a version value is within a valid range of values. The version can be for a file, application, or anything else that has a standard 4-part version. For example, you want to enforce that an application has a version of at least 2.0.0.0. If the version is actually 1.0.0.0, the constraint will raise an error. Also, you may need to make sure an application version is less than a maximum value. Note that you might also want the minimum or maximum versions to be inclusive or exclusive, depending on the needs of a particular constraint.

  1. Create a .sdm file named Microsoft.Samples.VersionConstraint.sdm.

    For more information on creating a .sdm file, see How to: Create a .sdmdocument File. Use the code below to start your .sdm file.

    [XML]

    <?xml version="1.0" encoding="US-ASCII"?>
    

<SystemDefinitionModel Name="Microsoft.Samples.VersionConstraint" Version="1.0.0.0" xmlns="https://schemas.microsoft.com/SystemDefinitionModel/2005/1" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:xs="https://www.w3.org/2001/XMLSchema">

&lt;Information&gt;
    &lt;FriendlyName&gt;Example of a custom constraint.&lt;/FriendlyName&gt;
    &lt;CompanyName&gt;Microsoft Corporation&lt;/CompanyName&gt;
    &lt;Copyright&gt;Copyright (c) Microsoft Corporation.  
        All rights reserved.  
        This is provided AS IS with no warranties, 
        and confers no rights.
    &lt;/Copyright&gt;
&lt;/Information&gt;

&lt;!-- Add constraint information --&gt;

&lt;!-- Add manager information --&gt;

</SystemDefinitionModel>

For more information on the XML elements used in the code above, see [**SystemDefinitionModel Element**](bb168334\(v=vs.90\).md) and [**Information Element**](bb168173\(v=vs.90\).md).
  1. Create a constraint definition.

    In the constraint definition, you provide the name of the manager that will be implementing the constraint and the class name (ClrClassName) that will be necessary later when you implement the manager. Add the following code to the .sdm file.

    [XML]

    <ConstraintDefinition 
    Name="VersionConstraint" 
    Manager="VersionConstraintManager" 
    ClrClassName="Microsoft.SystemDefinitionModel.Samples.VersionConstraint"/>

    For more information on the XML elements used in the code above, see ConstraintDefinition Element.

  2. Create a manager definition.

    For the SDM compiler to find the assembly with the implementation of the constraint, specify the manager information. In a later step you will provide the implementation for and compile Microsoft.Sdm.Samples.VersionConstraint.dll.

    [XML]

    <Manager Name="VersionConstraintManager" 
    

AssemblyName="Microsoft.Sdm.Samples.VersionConstraint" SourcePath="Microsoft.Sdm.Samples.VersionConstraint.dll"/>

For more information on the XML elements used in the code above, see [**Manager Element**](bb168178\(v=vs.90\).md).
  1. Add constraint settings.

    A constraint definition that compares settings is not useful without providing settings to compare. The settings provide the bridge between the constraint in the system definition model and managed code where the constraint is evaluated. A setting declaration must be provided for each setting that will be used to evaluate the constraint. For this example, you need the following five settings:

    • ActualVersion: The version of the application, file, or other object.
    • MinimumDesiredVersion: The minimum version of the range in which ActualVersion must fall.
    • MinimumDesiredVersionInclusive: Whether or not the MinimumDesiredVersion is inclusive. If false, ActualVersion cannot be equal to the minimum version.
    • MaximumDesiredVersion: The maximum version of the range in which ActualVersion must fall.
    • MaximumDesiredVersionInclusive: Whether or not the MaximumDesiredVersion is inclusive. If false, ActualVersion cannot be equal to the maximum version.
    1. In your .sdm file, replace the <ConstraintDefinition> element created in step 2 with the following <ConstraintDefinition> element. The following <ConstraintDefinition> element contains the setting declarations.

      [XML]

      <ConstraintDefinition 
      

    Name="VersionConstraint" Manager="VersionConstraintManager" ClrClassName="Microsoft.SystemDefinitionModel.Samples.VersionConstraint"> <Description>Verifies that a version is within the desired range.</Description> <SettingDeclaration Name="ActualVersion" Definition="Version" /> <SettingDeclaration Name="MinimumDesiredVersion" Definition="Version" CanBeNull="true" /> <SettingDeclaration Name="MinimumDesiredVersionInclusive" Definition="Boolean" /> <SettingDeclaration Name="MaximumDesiredVersion" Definition="Version" CanBeNull="true" /> <SettingDeclaration Name="MaximumDesiredVersionInclusive" Definition="Boolean" /> </ConstraintDefinition>

    1. When evaluating the constraint, all settings must be initialized before the SDM compiler will allow the constraint to be executed. A good practice is to provide default values for each of the settings if they are not required.

      In the code below, the default setting values are set such that the minimum and maximum versions are null. The constraint is implemented to interpret this as no restriction on the version. Also by default, the minimum and maximum versions are allowed to be inclusive.

      In your .sdm file, replace the <ConstraintDefinition> element created above with the following <ConstraintDefinition> element. The following <ConstraintDefinition> element contains the setting declarations and default values.

      [XML]

      <ConstraintDefinition 
      

    Name="VersionConstraint" Manager="VersionConstraintManager" ClrClassName="Microsoft.SystemDefinitionModel.Samples.VersionConstraint"> <Description>Verifies that a version is within the desired range.</Description> <SettingDeclaration Name="ActualVersion" Definition="Version" /> <SettingDeclaration Name="MinimumDesiredVersion" Definition="Version" CanBeNull="true" /> <SettingDeclaration Name="MinimumDesiredVersionInclusive" Definition="Boolean" /> <SettingDeclaration Name="MaximumDesiredVersion" Definition="Version" CanBeNull="true" /> <SettingDeclaration Name="MaximumDesiredVersionInclusive" Definition="Boolean" />

    &lt;!-- Default version range will be inclusive, but no minimum or maximum are specified --&gt;
    &lt;SettingValue Path="MinimumDesiredVersion" 
        Null="true" /&gt;
    &lt;SettingValue Path="MinimumDesiredVersionInclusive"&gt;true&lt;/SettingValue&gt;
    &lt;SettingValue Path="MaximumDesiredVersion" 
        Null="true" /&gt;
    &lt;SettingValue Path="MaximumDesiredVersionInclusive"&gt;true&lt;/SettingValue&gt;
    

    </ConstraintDefinition>

    For more information on the XML element used in the code above, see [**SettingDeclaration Element**](bb168223\(v=vs.90\).md) and [**SettingValue Element**](bb168322\(v=vs.90\).md).
    
  2. Implement the constraint.

    Now that you have created the .sdm file containing the constraint, you can provide the implementation for the constraint manager.

    1. Generate the manager for the constraint.

      The settings that were added to the <ConstraintDefinition> element need to have corresponding public properties in the C# implementation of the manager. The SDM Manager Generator (SdmG.exe) tool will translate the settings into C# properties. Run the following command line to generate the settings.

      SdmG.exe Microsoft.Samples.VersionConstraint.sdm /Constraints*+* **/Classes:**VersionConstraintProperties.cs

      This creates a C# file named VersionConstraintProperties.cs. In that file, you should see the following code:

      [C#]

      /// This file was generated using SdmG.exe, version=1.0.50228.0
      

namespace Microsoft.SystemDefinitionModel.Samples { using System;

public partial class VersionConstraint :
    Microsoft.SystemDefinitionModel.Manager.IConstraint
{
    public bool MaximumDesiredVersionInclusive;
    public Microsoft.SystemDefinitionModel.SerializableVersion
        ActualVersion;
    public Microsoft.SystemDefinitionModel.SerializableVersion
        MaximumDesiredVersion;
    public bool MinimumDesiredVersionInclusive;
    public Microsoft.SystemDefinitionModel.SerializableVersion
        MinimumDesiredVersion;
}

}

    In the code above, note:
    
      - The namespace and class name are derived from the **ClrClassName** attribute of the \<ConstraintDefinition\> element.
      - The generated class implements the [**IConstraint**](bb167942\(v=vs.90\).md) interface, although no implementation is provided for the [**IConstraint.Evaluate**](bb167943\(v=vs.90\).md) method.
      - The generated class is a partial class.
      - The SDM type **Boolean** translated to the C\# type **bool**.
      - The SDM type **Version** translated to the C\# type **SerializableVersion**.

2.  Implement the C\# code for the constraint behavior.
    
    Because the generated code is a partial class, you can define the implementation for the **IConstraint.Evaluate** method in a separate C\# source file named VersionConstraint.cs. Create a new C\# source file with the same class name as the generated VersionConstraint above and implementing the **IConstraint** interface. The following code implements the **IConstraint.Evaluate** method.
    
    #### \[C\#\]
    
    <pre IsFakePre="true" xmlns="https://www.w3.org/1999/xhtml">//------------------------------------------------

// <copyright file="VersionConstraint.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> // // <summary> // Sample to compare if a version is within a required range. // </summary> //--------------------------------------------------------

namespace Microsoft.SystemDefinitionModel.Samples { using System; using Microsoft.SystemDefinitionModel; using Microsoft.SystemDefinitionModel.Manager;

public partial class VersionConstraint : 
    Microsoft.SystemDefinitionModel.Manager.IConstraint
{
    private const int MinVersionOutOfRangeError = 500;
    private const int MaxVersionOutOfRangeError = 501;
    private const int VersionLessThan = -1;
    private const int VersionEquals = 0;
    private const int VersionGreaterThan = 1;

    /// &lt;summary&gt;
    /// Evaluate whether a version is within the
    /// minimum and maximum version.
    /// If neither the minimum or maximum versions are set,
    /// any version is allowed.
    /// &lt;/summary&gt;
    /// &lt;returns&gt;Array of errors detected when
    /// evaluating the constraint.&lt;/returns&gt;
    public ConstraintError[] Evaluate()
    {
        // If the minimum version is specified, 
        // check if the version is in range.
        if (this.MinimumDesiredVersion != null)
        {
            // Compare the actual version with the
            // minimum required version.
            int minVersionComparison = 
                this.ActualVersion.Version.CompareTo(
                this.MinimumDesiredVersion.Version);

            // If the actual version is less than, 
            // or is equivalent and not inclusive, raise an error.
            if (minVersionComparison == VersionLessThan ||
                minVersionComparison == VersionEquals &amp;&amp; 
                !this.MinimumDesiredVersionInclusive)
            {
                return new ConstraintError[] {
                    new ConstraintError(MinVersionOutOfRangeError,
                        String.Format(
                        "The version {0} is out of range. " + 
                        "The version must be greater than the minimum " +
                        "version {1}.", this.ActualVersion, 
                        this.MinimumDesiredVersion),
                        new String[] { "ActualVersion" })
                };
            }
        }

        // If the maximum version is specified, 
        // check if the version is in range.
        if (this.MaximumDesiredVersion != null)
        {
            // Compare the actual version with the
            // maximum required version.
            int maxVersionComparison = 
                this.ActualVersion.Version.CompareTo(
                this.MaximumDesiredVersion.Version);

            // If the actual version is greater than, 
            // or is equivalent and not inclusive, raise an error.
            if (maxVersionComparison == VersionGreaterThan ||
                maxVersionComparison == VersionEquals &amp;&amp; 
                !this.MaximumDesiredVersionInclusive)
            {
                return new ConstraintError[] {
                    new ConstraintError(MaxVersionOutOfRangeError,
                        String.Format("The version {0} is out of range. " +
                        "The version must be less than than the maximum " +
                        "version {1}.", this.ActualVersion, 
                        this.MaximumDesiredVersion),
                        new String[] { "ActualVersion" })
                };
            }
        }

        return null;
    }
}

}

  1. Compile the manager.

    Now you have all the code needed to compile the manager. Take the two C# files you created for the manager, and compile them with the C# compiler. The SDM SDK Command Prompt window sets a couple environment variables (SdmPublicAssemblies and V2ClrInstallDir) that will be needed for this compilation. Use the command line below to compile the C# files.

    **Csc.exe /noconfig /target:**library /reference:"%SdmPublicAssemblies%\Microsoft.sdm.manager.dll" /reference:"%SdmPublicAssemblies%\Microsoft.sdm.system.dll" /reference:"%V2ClrInstallDir%\System.Xml.dll" **/out:**Microsoft.Sdm.Samples.VersionConstraint.dll VersionConstraintProperties.cs VersionConstraint.cs ****

  2. Compile the .sdm file containing the constraint.

    At this point you have completed creating the constraint. Compile the .sdm file to produce the .sdmdocument file for the constraint, which can be referenced later. Make sure the manager assembly from the previous step is in the same directory as the .sdm document. Use the following command to compile the .sdm file containing the constraint.

    SdmC.exe Microsoft.Samples.VersionConstraint.sdm /Output Microsoft.Samples.VersionConstraint.sdmdocument

Using the Constraint

Now that you have defined the constraint and provided an implementation for it, you can use the constraint. The <Constraint> element is used with an <Input> child element for each of the settings that will be used by the constraint in the evaluation. For more information on how and where to use the constraint, see step 7 in the How to: Create an SDM Application System topic.

See Also

How to: Create an SDM Application System
IConstraint.Evaluate()
IConstraint

Send comments about this topic to Microsoft

Build date: 10/2/2007