Expression Evaluation Framework
A pluggable, secure, fully observable directive-based expression engine for BizFirst workflow automation.
{@ $ctx.user.name } or {@ $var.invoiceTotal @uppercase } and they are resolved at runtime by the appropriate directive.
Core Concepts
| Concept | What it is |
|---|---|
| Directive | A named plug-in that resolves a specific type of expression (e.g., $ctx, $var, $input) |
| Expression | A wildcard string inside a field value: {@ $directive.path @option } |
| Option | A post-resolution transform applied to the resolved value: @uppercase, @json, @cache |
| Template String | A field that contains one or more embedded expressions: Hello {@ $ctx.user.name }, your balance is {@ $var.balance } |
| Canned Expression | A named, reusable expression stored in the database, referenced as @aliasName |
| EvaluationContext | Execution state shared across all field resolutions in a single node invocation |
Built-in Directives
| Directive | Purpose | Example |
|---|---|---|
$ctx | Environment, tenant, user, time context | {@ $ctx.user.name } |
$var | Workflow memory variables | {@ $var.invoiceTotal } |
$input | Current node input data | {@ $input.current.email } |
$output | Output from a previous node | {@ $output.ParseNode.amount } |
$exec | Execution metadata | {@ $exec.executionId } |
$flow | Workflow metadata | {@ $flow.current.name } |
$js | Inline JavaScript (Jint sandbox) | {@ $js`return input.price * 1.1` } |
$cs | Inline C# (Roslyn, Trusted only) | {@ $cs`return input.Amount * TaxRate` } |
$tpl | Liquid template rendering | {@ $tpl.InvoiceEmail } |
$api | External HTTP API call | {@ $api.CurrencyService/rates/USD } |
$math | Math functions | {@ $math.round(2).of($var.total) } |
$items | Global item collection functions | {@ $items.count } |
@ | Canned expression alias | @company.taxRate |
Supported Syntax Flavors
Documentation Guides
How It Works
Pipeline architecture, parsing, directive routing, and template interpolation flow.
Integration Guide
DI registration, EvaluationContext setup, calling from node executors, handling responses.
Directive Structure
Anatomy of a directive: interfaces, base class, path resolution, chaining.
Expression Samples
Working examples for every built-in directive with common patterns.
Options Reference
All built-in options — transforms, validation, caching — with examples.
Nested Templates
Multi-expression template strings, multi-pass resolution, depth tracking.
Canned Expressions
Database-stored reusable expressions, aliasing, tenant/app scoping.
Complex Use Cases
Chaining directives, multi-step resolution, real-world workflow patterns.
Edge Cases
Null paths, depth limits, cycle detection, isolation violations, error codes.
Plugin Guide
Build your own directive for a third-party service or internal domain concept.
Discovery API
Self-describing metadata API powering the expression builder UI with autocomplete.
Vocabulary
Glossary of all terms: directive, path, option, token, context, isolation level.
Quick Project Map
| Project | Solution Folder | Responsibility |
|---|---|---|
Domain | Domain | All contracts, interfaces, enums, base classes |
Core.Services | Core | Orchestrator, parsers, options, validator, cache |
Catalog.Services | Directives | @ canned expression store and directive |
Context.Services | Directives | $ctx — env / tenant / user / time |
Memory.Services | Directives | $var — workflow variables |
NodeData.Services | Directives | $input, $output |
FlowExecution.Services | Directives | $exec, $flow |
Scripting.Js.Services | Directives | $js — Jint JavaScript sandbox |
Scripting.Cs.Services | Directives | $cs — Roslyn C# sandbox |
Template.Services | Directives | $tpl — Liquid/Fluid templates |
Api.Services | Directives | $api — HTTP API calls |
Functions.Services | Directives | $math, $items |