RuleFlow

Lightweight, developer-friendly rule engine for .NET

View the Project on GitHub rubenrichtering/RuleFlow

A rule ties a condition to one or more actions, with optional metadata and execution hints. Playground: Conditional Chains (ConditionalChainsScenario.cs), Basic Rules (BasicRulesScenario.cs).

When (conditions)

If the condition is false, the rule’s actions do not run (the rule may still appear in traces depending on options).

Dynamic conditions (ConditionNode)

Rules can also be driven by a structured condition tree (ConditionNode) instead of a C# lambda. That tree is data (JSON, database, UI): no expression parsing, no compiled code. At runtime, RuleDefinitionMapper<T> turns a persisted RuleDefinition.Condition into a .When((input, ctx) => evaluator.Evaluate(input, node, ctx)) so execution matches the same When / engine pipeline as hand-written rules.

See Dynamic conditions for the model (ConditionLeaf, ConditionGroup), operators, nested property paths, and JSON examples. Playground: DynamicConditionsScenario.cs.

Then (actions)

You can chain multiple steps; they run in order.

ThenIf (conditional steps)

Run a step only when an extra predicate holds:

Rule.For<Order>("High amount processing")
    .When(o => o.Amount > 1000)
    .Then(o => { o.RequiresApproval = true; })
    .ThenIf(o => o.Customer?.IsPremium == true, o =>
    {
        // Premium path
    })
    .ThenIf(o => o.Customer?.IsPremium == false, o =>
    {
        // Standard path
    })
    .Because("Amount exceeds approval threshold");

Because (reason)

.Because("…") records why the rule exists. It appears on RuleExecution.Reason and in explainability output.

Priority and stop processing

Metadata

.WithMetadata(key, value) attaches data you can filter on at execution time via RuleExecutionOptions (see Metadata in ExecutionOptionsScenario.cs).