Data Context
Typed variable store shared across all tasks in a workflow execution
What Is the Data Context?
The Data Context (IWorkflowDataContext) is the communication backbone of every Aurora workflow execution. Each task receives the same context instance (or a child derived from it) and uses it to read inputs and write outputs. It acts as a strongly-typed, key-value dictionary keyed by .NET type and an optional custom string key.
Creating a Context
var context = WorkflowDataContext.Create(workflow);
// Pre-populate variables before starting:
context["myKey"] = "some value";
context[typeof(int)] = 42;
Core API
| Method / Property | Description |
|---|---|
this[string key] | Get or set a value by raw string key. |
this[Type type] | Get or set a value by .NET type (uses the type's full name as key). |
void Set(object value, string customKey) | Store a value. If customKey is omitted the type name is used. |
T Get<T>(string customKey) | Retrieve a typed value. Returns the default if not found. |
object Get(Type type, string customKey) | Retrieve an untyped value by type. |
object Get(string customKey) | Retrieve an untyped value by raw key. |
T GetOrCreate<T>(string tag, string customKey) | Returns the stored value or creates and stores a new instance via the default constructor. |
T TryGet<T>(string customKey) | Like Get<T> but returns default(T) instead of throwing when not found. |
bool Has<T>(string customKey) | Returns true if a value for that type/key exists in the store. |
IDictionary<string, object> GetAll() | Returns a detached snapshot of all stored key-value pairs. Modifying the returned dictionary does not affect the context. |
void Clear() | Removes all stored values. |
void MergeFrom(IWorkflowDataContext) | Copies all entries from another context into this one (last-write wins). |
IWorkflowDataContext Clone() | Creates a shallow copy: entries are copied, the stored values themselves are shared. |
Guid SessionIdentifier | Identifies the current execution session. Shared across all tasks in one run. |
Guid Id | Unique identity of this specific context instance. |
IWorkflow Workflow | Reference back to the owning workflow. |
GetOrCreate<T> is atomic, so parallel tasks never observe two different instances for the same key.Scope-Aware Access: ScopedDataAccessor
The raw context is intentionally simple. All task-level semantics – custom input/output variable names, the __LASTOUTPUT marker and parent/global scope selection – live in ScopedDataAccessor. Tasks use it implicitly through GetInput<T>(context) / SetOutput(context, value), but hosting code, tests and tooling can obtain the same behaviour for any object implementing IVariableScopeSettings (every task does):
// Read/write exactly as the task itself would
var data = context.For(task);
data.SetOutput("result", 42); // honours CustomOutputVariableName, scope flags and __LASTOUTPUT
var value = data.GetInput<int>("result");
var previous = data.GetPreviousTaskOutput();
// Resolve the effective scopes
IWorkflowDataContext inputScope = data.GetInputScope();
IWorkflowDataContext outputScope = data.GetOutputScope();
IWorkflowDataContext global = data.GetGlobalVariableSpace(); // falls back to the local context when no global scope is injected
| Member | Description |
|---|---|
GetInput<T>(name) / GetInput(name) | Custom input variable first, then the named variable (defaults to the type name), then __LASTOUTPUT if it is assignable to T. |
SetOutput(name, value) | Writes to the effective output scope. In the local scope the value is also stored under its type name and as __LASTOUTPUT; parent/global writes do not touch __LASTOUTPUT to keep parallel tasks independent. |
GetPreviousTaskOutput() | Reads __LASTOUTPUT from the effective input scope. |
GetVariableScope(), GetInputScope(), GetOutputScope() | Resolve the default, input and output scopes from the task's Use* flags. Parent takes precedence over global; a missing parent scope falls back to global/local. |
SetErrorState(exception, taskName) / ClearErrorFlag() | Maintain the __ERROROCCURED flag and the EX_<taskName> entry used by ContinueOnError. |
Well-known keys are exposed as constants in WorkflowDataContextKeys (LastOutput, ErrorOccured, GlobalVariable, ParentScopeVariable).
Scope Inheritance
Scope tasks (ForEachTask, LoopTask, ConditionalScope, etc.) create a child context for the tasks they contain. By default, child tasks read from and write to this local scope. Use the following task properties to control scoping:
UseGlobalScopeForInput– the task reads its input from the top-level workflow context.UseGlobalScopeForOutput– the task writes its output to the top-level workflow context.UseParentScopeForInput– the task reads from the direct parent scope.UseParentScopeForOutput– the task writes to the direct parent scope.
Using Variables in Expressions (Property Fields Only)
DoAsync etc.) use GetInput<T>(context), SetOutput(context, value) and Resolve<T>(property, context) (or context.For(this) for the full scope-aware accessor). Direct access bypasses scope resolution and variable name configuration and will cause incorrect behaviour.Inside a = prefixed expression, every variable that is visible in the current scope is injected as a typed C# local with its variable name. Variables of the global scope are additionally available as _global_<name>, variables of the direct parent scope as _parent_<name>. The raw dictionary is available as DataContext. Examples:
// Read a string variable named "fileName"
=fileName.ToUpper()
// Compute from two variables
=width * height
// Global variable from inside a nested scope (e.g. a loop body)
=Path.Combine(_global_baseDir, fileName)
// Check presence via the raw dictionary
=DataContext.ContainsKey("apiKey") ? (string) DataContext["apiKey"] : "default"
Pre-populating Variables (CLI / Hosting)
Before calling StartAsync, populate the context with any values that tasks should see as inputs:
var context = WorkflowDataContext.Create(workflow);
context["inputFile"] = @"C:\data\report.csv";
context["maxRows"] = 1000;
context["dryRun"] = true;
await workflow.StartAsync(context);
The CLI Runner does this automatically by mapping --key value command-line arguments to string entries in the context.