Extending logic

◷ Reading Time: 5 minutes

Introduction

There are some scenarios when validation conditions require communication back to the application or execution of a custom behaviour. These situations can be categorised into two areas:

  • Validate a custom condition
  • Take a custom action

In these scenarios, you can use Check command to extend the validation engine.

Custom condition

Sometimes in validation rules, you may need to access an external resource, or for example, implement a custom condition to participate in a validation chain. You can accomplish these tasks simply by using either Alias or Check.

Using Check

To use the Check command you need to

  1. Add an input parameter to the rule
  2. Pass the defined parameter value to the rule when it is called
  3. Call Check command in the chain of the conditions

The following sample rule defines an input parameter and calls the custom logic using Check

<Validation name="PersonValidation">
  <Declaration>
    <Define name="MinAge" direction="In"/>
	<!-- Define the input parameter -->
    <Define name="fin" direction="In" />
  </Declaration>
 
  <Logic name="Logic with custom call">
    <Group>
      <Check value="fin.DbExists($this)"/>
      <And />
      <Null value="Name" negate="true"/>
      <And />
      <Empty value="Name" negate="true"/>
      <Or />
      <Null value="Family" negate="true"/>
      <And />
      <Empty value="Family" negate="true" />
    </Group>
  </Logic>
 
</Validation>

The following code is the class definition of the fin parameter

class PersonDbAccess
{
    public bool DbExists(object obj)
    {
        Person person = (Person) obj;
        // Check if the person exists
 
        return false;
    }
}

Sending Information to Method

Sometimes it is necessary that the method which implements Alias receives some additional information. This additional information is available via AliasContext. In AliasContext your code has the ability to access some settings of the alias command and make decisions based on these. By using this mechanism, the rule command can pass information to the method.

For example, in the following code we are passing a name attribute to the method in order to make a decision based on this:

<Validation name="PersonValidation">
  <Declaration>
    <Define name="MinAge" direction="In"/>
    <!-- Define the input parameter -->
    <Define name="fin" direction="In" />
    <!-- Define Alias for method DbExists named as FindPersonRecord -->
    <Alias method="fin.DbExists" as="FindPersonRecord"/>
  </Declaration>
 
  <Logic name="Logic with custom call">
    <Group>
      <FindPersonRecord name="5044162C-3DAA-499C-87DC-E325366B10E3" />
      <And />
      <Null value="Name" negate="true"/>
      <And />
      <Empty value="Name" negate="true"/>
      <Or />
      <Null value="Family" negate="true"/>
      <And />
      <Empty value="Family" negate="true" />
    </Group>
  </Logic>
 
</Validation>

The method looks similar to the following code. It also allows you to check for more detail about the Alias information by the IAliasInfo interface.

class PersonDbAccess
{
    public bool DbExists(AliasContext context, object obj)
    {
        // Check for the Alias information: Name, Method and Reference
        var aliasInfo = context.Alias;
 
        // Check for the command settings
        if (context.Dictionary.ContainsKey("name"))
        {
            string name = context.Dictionary["name"];
            // Do what it is required with 'name' here
        }
 
        Person per = (Person)obj;
        // Check the person record
 
        return true;
    }
}

Custom actions

In the logic of the validation, you can have a Then section. If the logic condition is satisfied, Then will be executed. There are two actions you may want to take in the Then section:

  1. Set a variable value
  2. Call your custom action

Set variable value

To set a variable value in the rule you simply define some output parameters and set them using the Var command.

<Validation name="PersonValidation">
  <Declaration>
    <Define name="MinAge" direction="In"/>
    <!-- Define an output parameter to be set in Then section -->
	<Define name="state" direction="Out" />
  </Declaration>
 
  <Logic name="basic validation 2">
    <Group>
      <Check value="Age < MinAge"/>
    </Group>
    <Then>
      <Var name="state" value="0i" />
    </Then>
  </Logic>
</Validation>

Call your custom action

Create a custom cakes and inject it to your model using Input parameters.

class PersonDbAccess
{
    public void WriteDb(object obj)
    {
        Person person = (Person) obj;
        // Do whatever is required for the person
    }
}

Then use the expression and call them an object member. In this case, the method of the object.

Next sections

In the next couple of articles, we will cover different aspects of modeling and executing the validation rules using Validation logic.

  1. Introduction to validation rules
  2. Validating hierarchy (Inheritance relation)
  3. Validating association (Aggregation, Composition)
  4. Validation rule execution and collecting results
  5. Pass extra input values to validation rules
  6. Extending validation conditions and actions
  7. How to apply rules under some conditions
  8. Referencing commonly used logic
  9. Sample for Order processing validation logic
Updated on March 30, 2020

Was this article helpful?

Related Articles