Search code examples
rule-engineinrule

Best means of defining constants or named values


What is the best way to define constants or named values in InRule?

e.g. I don't want a bunch of magic numbers (that can be easily duplicated). For example "minimum age". I would like to define a named constant that I can use like MinimumAge in place of a value like 21.


Solution

  • There are a number of different ways to approach this. I'll outline a couple general approaches that can address your question.

    With a bit of design consideration, you can use fields initialized to default values that can be overridden by passing in (from the calling application) appropriate configuration data to the rules engine.

    1. Calculated or initialized entity field

    Create a calculated field on an entity, setting the expression value to the desired constant. This doesn't scale well as additional constants are added and additional root context entry points are implemented.

    To manage this growth in complexity, there are a number of variations on this pattern that mitigate the above are almost straight from Fowler's Refactoring:

    • Extract configuration data into a (parameter) object
    • Instead of using a calculated field, write an Initialization Ruleset. An Explicit RuleSet is recommended to give fine control over initialization time. In a controlling ruleset, add Execute RuleSet actions that invoke your init rules. EDIT: corrected guidance

    2. Inline data table

    Create an inline table to hold these and other constant values used by your rules. You'll then look up the appropriate value (see above paragraph about intialization rulesets as the concepts apply here as well).

    By structuring your rules appropriately you can rephrase the problem from "What is the best way to defined constants?" to "How do I write data-driven behavior into my rules?".

    Having a discussion and making the decision as to where and who will own the config/const type of data is important and is both a business and an architectural decision.

    3. Define a Vocabulary template (applies to all approaches)

    An expression template returning the desired constant can be a neat way to enable users to write rules like the following (constants in bold):

    If the applicant is under the minimum age, set base score to minimum base score

    Whatever approach you decide upon, in all but the simplest scenarios you should consider using Vocab templates to facilitate reuse and reduce friction for rules authors. Vocab is great because it is essentially an arbitrarily-defined reusable, parametric function. The downside of it is that rules must be written in BL (Business Language) in order to take advantage of a Vocab template.

    For example, if you decide to use a look-up table to store constants, you can create an Expression template that calls GetMember or TableLookup. Instead of forcing users to write the same table lookup statements all over the place, you've consolidated that lookup logic into a central statement of Vocab