Navigation

Categories
Show Navigation Next Topic  »

Code Effects Basics

Code Effects business rules engine allows creation, modification, validation, and evaluation of complex business rules - as well as creation and execution of complex rule-based data filters for virtually all established LINQ providers. Using its web interface, business users can create rules or filters by selecting options from a series of context-sensitive drop-down menus. This IntelliSense-like approach is unique to web-based business rule management. With Code Effects integrated into your project, the most complex business rules can be authored without any knowledge of programming languages.

The concept of Code Effects is quite simple: create a business rule online using the Rule Editor, save it anywhere as an XML document, and evaluate any number of instances of your source object against that rule in any .NET code using one of the Evaluator classes.

Code Effects engine can also be used to run very powerful data filters. It uses a simple notion that with the right user interface any evaluation type business rule such as this:

Check if Product SKU starts with A123 or Shipping ZIP is 30022

... can also be interpreted as a where clause in a select statement against a database:

Get all records where Product SKU starts with A123 or Shipping ZIP is 30022

This feature is called Rule-Based Data Filtering. It's implemented as a LINQ extension method and available in all versions of Code Effects. Details can be found here.

Code Effects engine is not an environment. It simply provides a way to create and evaluate rules and data filters. Contrary to most traditional business rule management systems that run as independently installed processes, Code Effects solution is designed to be an internal part of your new or existing .NET web application, or at least the rule authoring part of it. As such, it does not include rule debugging, versioning, rule access authorization mechanisms or any other functionality to help manage your rules. Your web application is your environment. If needed, all of that functionality can be implemented by using standard APIs and tools that are built into the .NET framework and Code Effects.

While the above is true for rule authoring, rule evaluation is a bit different. Once rules are created and are ready to be used, Code Effects engine provides an extremely easy way to evaluate your rules against source objects by any .NET process, service or program, not just web applications. You can have any number of Windows, WCF or any other types of services, running in different parts of the world, all receiving data from different sources. Those services can retrieve XML rules from your common storage and evaluate them against incoming objects, inspecting the result of each execution and acting accordingly, or let actions inside of each execution type rule determine the further processing of the object.

More details on this matter are provided in this topic.

Another unique feature of the Code Effects engine is its use of parentheses to prioritize evaluation of each condition in the rule. This dramatically simplifies the rule creation and modification process.

Below is the list of elements behind Code Effects technology that you need to understand in order to successfully author and evaluate business rules:

  • Business Rule. Code Effects engine supports two types of rules:

    • Evaluation type:

      Check if ( A is equal to 10 or B has any value ) and C is greater than A
    • Execution type:

      If

         ( A is equal to {2 + B} and C is less than A )

            or B is greater than Get Some Value (parameter)

               then set C to 10 and Invoke Action One

      Else if

         D contains xyz or C has no value

               then set D to abc and Invoke Action Three and Invoke Action Four

      else

         Invoke Action Two

    Supporting multiple rule types gives applications and rule authors much greater flexibility in fine-tuning business processes. Make sure to read their respective topics here and here.

    Each rule consists of rule elements which we will refer to throughout this website:

    • Flow: Elements if, else if and else are flow elements. The if element is required in any rule, while the others are optional. Flow elements divide each rule into sections. Obviously, evaluation type rules can have only one if flow element, and therefore rules of this type always have only one section. Execution type rules can be divided into multiple sections, with each section having one or more actions (.NET methods) or value setters. Actions and setters will be invoked only if the entire section evaluates to True. There can be only one if, one else, and any number of else if flow elements per each execution type rule. To complicate things a bit more, each rule section can be divided into levels by using parentheses. See the definition of Clauses below to find out why all these definitions are important. The default English display names of all flow elements can be changed by using custom Help XML files.
    • Fields: Elements A, B, and C in the examples above are rule fields. They represent public fields and properties of the source object. By default, each field displays its name as it's declared in the source object. This can be changed by decorating fields and in-rule methods (explained later in this document) with the FieldAttribute or MethodAttribute respectively and setting their DisplayName properties to any label in any language. You can also reuse previously saved evaluation type rules in other rules as if they were fields or properties. It's a very cool feature, read more about it here.
    • In-Rule Methods: Element Get Some Value in the executable rule example above is an in-rule method. In-rule methods play the same role as rule fields except they are actually methods of source objects or any other .NET public class. In-rule methods are invoked by Rule Engine during rule evaluation. Rules of both evaluation and execution type can use in-rule methods. The .NET methods they represent must return a value type. They can be instance or static methods, have overloads and be parameterless, or have any number of parameters of value types or parameters of the source object's type. As with rule actions, if a method has multiple overloads you need to set a unique value of the DisplayName property of MethodAttribute for each overload if you'd like to use that overload in your rules as a separate in-rule method. Decorate unwanted overloads with ExcludeFromEvaluation attribute. Parameterless in-rule methods display no signatures (no parentheses), so they appear as regular rule fields to the rule author. All aspects of in-rule methods can be controlled by MethodAttribute, ExternalMethodAttribute, ParameterAttribute, and ReturnAttribute classes.
    • Values: Elements 10, { 2 + B } and xyz are field values. Rule authors can use calculations, input or even other fields to set field values in rules. Values do not have their own attribute class. Their settings, such as minimum or maximum allowed value, case sensitivity, date format, and so on, are normally controlled by the FieldAttribute or ReturnAttribute.
    • Operators: Elements is equal to, has any value, and so on are rule operators. They represent equation operators =, <, > and others. By default, operators are displayed as English phrases such as is greater or equal to instead of which makes them easier for non-technical users to work with. The default display names of all operators can be changed by using custom Help XML files.
    • Conditions: Condition is a combination of field-operator-value elements. Each rule section must contain at least one condition, otherwise the rule is considered invalid.
    • Actions: Shown in the executable rule example above, elements Invoke Action One, Invoke Action Two and so on are rule actions. Rule actions are used only in execution type rules. A single rule section can have any number of actions, which are public methods declared in the source object or any other .NET public class. Action methods must return System.Void; they can be instance or static methods, have overloads and be parameterless, or take any number of parameters of value or source object types. By default they are displayed using the declared names of methods they represent. As with in-rule methods, if an action method has multiple overloads you need to set a unique value of the DisplayName property of ActionAttribute for each overload if you'd like to use that overload in your rules as a separate action. Decorate unwanted overloads with ExcludeFromEvaluation attribute. Parameterless actions display no signatures (no parentheses.) All aspects of rule actions can be controlled by ActionAttribute, ExternalActionAttribute and ParameterAttribute classes.
    • Setters: As shown in the execution type rule example above, a value setter is a combination of set-field-to-value. A single rule section can have any number of setters as well as any number of actions. Rule authors can use setters to set properties of the source object to certain values if the entire section evaluates to True.
    • Clauses: Evaluation type rules use only two clauses - and and or. These correspond to the && and || operators of most programming languages. A single level of a rule section can contain only and or or clauses but never both of them. To illustrate the last phrase, imagine the following rule:
      Check if
      	A is equal to B or B contains abc and C is not equal to A or
      		( C has no value and A starts with xyz or A doesn't end with opq )
      A level is a collection of one or more conditions that gets evaluated as a whole unit (see the definition of Flow above for details). Typically, each part of a section separated with parentheses is a single level. The entire section is a single level if that section doesn't have parentheses. In this rule, there is only one section (because it's an evaluation type rule) that contains two levels - the "main" level, and the "child" level separated from the main level with parentheses. As currently written, the rule above would not pass Code Effects' automatic validation because there are clauses of different types on each level. Try to "evaluate" this rule in your head and you'll see that it returns the worst thing in business rules - an unpredictable result. Unpredictable for the rule author, that is. The author either has to add some parentheses or change clauses to make this rule valid. Let's do all that so you can see the difference:
      // Changing clauses...
      
      Check if
      	A is equal to B or B contains abc or C is not equal to A or
      		( C has no value and A starts with xyz and A doesn't end with opq )
      
      // ... or adding proper level separation
      
      Check if
      	A is equal to B or ( B contains abc and C is not equal to A ) or
      		( C has no value and ( A starts with xyz or A doesn't end with opq ))
      It is obviously illogical to use clauses of different types on the same level. The Rule Editor automatically validates all clauses in all levels when a rule author tries to save or update a rule.

      The execution type rules also include a then clause. It "attaches" one or more rule action to a single flow section. The default English display names of all clause elements can be changed by using custom Help XML files.
    • Collections: Code Effects engine natively supports properties of IEnumerable and IQueryable interfaces. The UI that implements this support is unique in the IT industry and explained in detail in this topic.

    Most of the traditional BRMS systems treat each condition as a single rule, combining those rules into rulesets. One of the goals of a ruleset is to handle the evaluation priority of each rule. So, a typical ruleset would look like this:

    ruleset:
    	// rule # 1
    	priority: 10
    	when: color = "red"
    	then: action 2
    
    	// rule # 2
    	priority: 1
    	when: color = "green"
    	then: action 1
    
    	// rule # 3
    	priority: 100
    	then: action 3
    end
    

    Because Code Effects business rules engine handles the evaluation priority of each condition automatically by using parentheses and/or flow elements, there is no need to combine conditions in rulesets (you can store multiple rules in a single XML file called ruleset, but that's a subject of a different topic.) In Code Effects, everything inside the rule area is a rule. This simplifies rule authoring and makes it much easier to use for non-programmers. The above rule would look very different in the Rule Editor:

    if color is equal to green then action 1
    else if color is equal to red then action 2
    else action 3
    
  • Source Object. Source objects are .NET classes your rules are evaluated against. In the BRE community these objects are also known as fact sources, fact objects, or just facts. Any .NET public class can serve as a Code Effects source object, provided that the source object itself, its base class, or any of its public members declares at least one public property of value type or a public method that returns a value type. Code Effects component "scans" the source object for those properties and methods and uses them as rule fields and in-rule methods.

    Although perfectly acceptable, you would rarely use a plain .NET class as a source object for your rules. Almost all its members can be greatly customized by using attributes included in the CodeEffects.Rule.Attributes namespace. Please read the topics on source objects and attributes for details.

  • RuleEditor and RuleModel classes. Code Effects rules engine provides implementation of Rule Editor for all modern .NET web platforms including ASP.NET Core 2.0. Read the Code Effects Implementation Examples for details and NuGet links for each platform.

  • Evaluation classes are declared in the CodeEffects.Rule.Core namespace. Those classes provide the rule evaluation functionality. The extremely simple implementation of rule evaluation hides its truly remarkable capabilities:

    string rule = ruleEditor.GetRuleXml();
    Evaluator<SourceObjectType> evaluator = new Evaluator<SourceObjectType>(rule);
    bool success = evaluator.Evaluate(sourceObjectInstance);

Post your questions on Stackoverflow and become a part of our growing community

Comments: 0