Evaluating Rules from the Rule Repository

The Rule Repository stores your rules and decides which version of each one is live. Your production applications evaluate those live versions with the Rule Engine, exactly as they would evaluate rules from any other storage. This page shows how to load them, which method to use, how to keep the compiled rules, and when to load them again.

Two Ways to Load Live Rules

Method Use it when Package
AuditRecorder.GetRules(..) Your application records its evaluations with Audit. Rules loaded any other way are evaluated but never recorded. CodeEffects.Rule.Audit
Context.GetRules(..) Your application does not record its evaluations. CodeEffects.Rule.Repository

Both take a RuleQuery and read the same live versions. Each returns the rules the query names plus every reusable or inline rule they call, through every level of calls, as one ruleset ready for the engine. A rule calls the live version of another rule, so the evaluator needs no rule resolver.

Only live versions are ever loaded. A version is evaluated in production once someone makes it live in the Rule Repository; see Live Versions and Approvals.

Naming the Rules

using CodeEffects.Rule.Common.Models;   // RuleQuery

// By ID: the rule IDs the Rule Repository shows
var byIds = RuleQuery.ByIds(new Guid("0b6f3c1e-5a7d-4c2b-9e41-2f6d8a9b1c30"));

// By name, narrowed to one source object when names repeat across sources
var byNames = RuleQuery.ByNames("Approve large orders", "Hold risky orders").InSource("Acme.Orders.Order");

// Every rule of a source object that has a live version, by the source object's alias
var bySource = RuleQuery.BySource("Acme.Orders.Order");

// Only the evaluation type rules of a source object
var evaluationOnly = RuleQuery.BySource("Acme.Orders.Order").OfType(evaluationType: true);

A source object's alias is its full class name without the assembly, unless your application gave it another one when it synchronized it; see Source Sync and Versioning.

Without Audit

Context.GetRules(..) takes the Rule Repository's database provider and returns a LoadedRuleset:

using CodeEffects.Rule.Engine;
using CodeEffects.Rule.Repository;

LoadedRuleset ruleset = Context.GetRules(dbProvider, RuleQuery.BySource("Acme.Orders.Order"));

var evaluator = new Evaluator<Order>(ruleset.Xml);

var approve = ruleset.Rule("Approve large orders");
bool approved = evaluator.Evaluate(order, approve.Id);
  • Xml is the ruleset for the engine.
  • Rules lists the rules you asked for first, then the rules they call (IsCalled is true for those). Each LoadedRule names its version (RuleVersionId, RuleVersionName) and its source version, so you know what you are running.
  • Rule(name) and Rule(id) find one rule, or return null.

It throws a RuleException when no rule the query names has a live version, when a rule asked for by ID or name does not exist or has no live version, and when a rule calls a rule with no live version. It throws a ConnectionException when the database is behind the version the library needs.

With Audit

An application that records its evaluations loads every rule through its AuditRecorder, attaches the recorder to the evaluation parameters, and creates the evaluator with those parameters:

AuditRuleset ruleset = audit.GetRules(RuleQuery.BySource("Acme.Orders.Order"));

var parameters = new EvaluationParameters();
audit.Attach(parameters);

var evaluator = new Evaluator<Order>(ruleset.Xml, parameters);

The ruleset Audit returns carries the stamps each record needs, so give its Xml to the evaluator as it is. See Recording Evaluations for the scope of each evaluation, its error codes, and shutting down.

Keep the Evaluator

Loading rules reads the database, and creating an Evaluator compiles every rule of the ruleset: both are expensive, while evaluating is cheap. Load and compile once, keep the ruleset and the evaluator, and reuse them for every evaluation. An evaluator can be shared between threads; see Evaluation Performance Tips.

Load Again When a Version Goes Live

A kept evaluator runs the versions it was compiled with. When someone makes another version live, your application runs it only after it loads the rules again. Choose how:

  • On a schedule, such as every few minutes.
  • When your application restarts or redeploys.
  • When the Rule Repository tells you. If the same application hosts the Rule Repository, its notifications say the moment a version goes live or is taken offline:
using CodeEffects.Rule.Repository.Common;   // NotificationAction

configuration.Notify = (action, data) =>
{
    if(action == NotificationAction.RuleVersionMadeLive || action == NotificationAction.RuleVersionTakenOffline)
        orderRules.Reload();
};

Load the new ruleset and compile the new evaluator first, then swap them in, so evaluations never wait for a reload. Recording Evaluations has a complete service that does this.

Taking the last live version of the rules a query names offline makes the next load throw; decide what your application does without the rule.

Ask on Stack Overflow - Yes, it's still active
Ask in GitHub Discussions

p102

l097 --

l102

p101

×