Rule Steps (Advanced)
  • Updated on 13 Mar 2019
  • 4 minutes to read
  • Print
  • Dark
    Light

Rule Steps (Advanced)

  • Print
  • Dark
    Light

Although it is easier to write simple rules see Rule steps (simple) for instructions on registering simple public bool methods as rules}, you may want to take the time to write an advanced rule that will give you more flexibility over how the rule is displayed in the rule designer. This also allows for custom design time validation both of which provide for a better user experience when configuring the rule in the rule designer.

Note
custom codes are located here: C:\Program Files\Decisions\Decisions Services Manager\Instances\Control\CustomReferences

To create an advanced rule, create a public class and decorate with the AutoRegisterRuleStep attribute. This attribute has four properties.

  • string name -- This property sets the name of your rule which will show up in the rule designer.
  • System.Type anchorType -- This property sets the type your rule will mainly interact with. This property is used to limit the rules that are shown in the rule designer based on which anchor data is selected for a rule statement. For example if you set this value to int32 your rule will not show up as a possible choice in the designer if you select a string as anchor data.
  • bool anchorTypeIsList -- Similar to the anchorType property, this property is used to limit which rules show in the rule designer based on the anchor data selected. However, this property limits the rules shown based on whether or not the anchor data is or isn't an array.
  • params string[] categories -- This property sets a category in which your rule will be displayed in the rule designer

Here is an example showing how to decorate your class.

 [AutoRegisterRuleStep("String Has Value", typeof(string), false, "Sample SDK Rules")]
public class SampleRule : AbstractRuleStep

The previously decorated class would show in the designer like:

StringHasValue-1.png

After decorating your class with the AutoRegisterRuleStep attribute, configure your class to inherit from AbstractRuleStep . This interface provides a default implementation for all the methods of the IRuleStep interface. You can customize these default implementations by overriding them. The following examples show how to override the most common methods.

The first method you will want to override is the Run method. The default implementation of this will always evaluate false . The following example snippet shows how to override the run method to evaluate if the anchor data is not null or empty

 public override bool Run(RuleStepExecutionData data)
{
    return (data.Data[this.AnchorData.Name] != null && data.Data[this.AnchorData.Name] != string.Empty);
}

When used in the rule designer, this is what the rule will look like when configured to evaluate Flow Data.InitiatingUserEmail as the anchor data. Notice how the rule has no description of what it is doing. The description, or rule verb, will be demonstrated next.

DefaultDataSource.png

Next you will likely want to give your rule a verb. This verb is used by the designer to describe in sentence form what your rule is doing. To give your rule a verb, override the GetVerbInfo method as follows.

 public override string GetVerbInfo(IInputMapping[] mappings)
{
    return "Has Value";
}

This configuration will look as follows:

HasValue.png

The above rule has no input data because it is only evaluating whether or not the anchor data has value. However, there are many times when a rule needs to have input data (see: Flow Steps and Rule Steps (Advanced) : Consuming Data for more on adding input data to your rule). In cases where your rule has input data, you will want to also override the GetValueInfo method to format how this input data appears in the text of your rule. The below sample code shows an example of input data and how to format this data to show up clean in the rule designer.

 public override DataDescription[] InputData
{
    get
    {
        return new DataDescription[]
            {
                new DataDescription(new DecisionsNativeType(typeof(string)), "value"),
            };
    }
}
public override string GetValueInfo(IInputMapping[] mappings)
{
    string value = "[Not Specified]";
    IInputMapping valueMapping = (mappings ?? new IInputMapping[0]).FirstOrDefault(m => m != null && "value" == m.InputDataName);
    if (valueMapping != null)
        value = base.GetValueInfo(valueMapping);
    return value;
}

The above configuration would render like this before selecting input data:
NotSpecifiedValue.png

The above configuration would render like this if value was configured to "tom@decisions.com "

CompletedRule1.png

In addition to input data, you may also want a rule to have a property.

Example 2

The following example shows how to construct a rule with a property value. This rule evaluates the length of a string to see if its length is less than a number property.
The property of the rule would be written like this:

 [WritableValue]
private int number;
[PropertyClassification(0, "Number", "Settings")]
public virtual int Number
{
    get { return number; }
    set
    {
        number = value;
        OnPropertyChanged("Number");
    }
}

The run method would use the property like this:

 public override bool Run(RuleStepExecutionData data)
{
   return (((string)data.Data[this.AnchorData.Name]).Length < number);
}

This property would show up in the rule designer as a value that can be hard coded. It looks like this.

LengthIsLessThan.png

We may also want to add some design time validation to our rule which would prevent the user from entering a number value less than 1. To do this, you will need to configure your class to inherit from and implement the IValidationSource interface. You'll also want to add InvalidateVerbInfo(); to you property's set so that the validations show up correctly in the designer when the value of your property is changed. The property and implemented IValidationSource would look like the following.

 [WritableValue]
private int number;
[PropertyClassification(0, "Number", "Settings")]
public virtual int Number
{
    get { return number; }
    set
    {
        number = value;
        OnPropertyChanged("Number");
        InvalidateVerbInfo();
    }
}
public ValidationIssue[] GetValidationIssues()
{
    List<validationissue> issues = new List<validationissue>();
    if (number < 1)
        issues.Add(new ValidationIssue(this, "Number must be greater than 0", null, BreakLevel.Fatal, "Number"));
    return issues.ToArray();
}</validationissue></validationissue>
Was this article helpful?