Repository navigation
5.5.2.2.1. Data Flow
An object flow carries typed tokens between Activity nodes. In UML diagrams it is normally shown as a directed edge, optionally labeled with the carried object. In Stateflows, declare its token type with AddFlow<TToken>(target).
Action nodes publish values with Output or OutputRange; downstream actions read the values selected for their activation with GetTokensOfType<TToken>().
.AddAction(
"CreateOrder",
async c => c.Output(new Order("ORD-42", [new Item("Book", 12m, 2)])),
node => node.AddFlow<Order>("CalculateTotal"))
.AddAction(
"CalculateTotal",
async c =>
{
var order = c.GetTokensOfType<Order>().Single();
c.Output(order.Items.Sum(item => item.Price * item.Quantity));
},
node => node.AddFlow<decimal>("DisplayTotal"))
.AddAction(
"DisplayTotal",
async c =>
{
var total = c.GetTokensOfType<decimal>().Single();
await display.ShowAsync(total, c.CancellationToken);
})The TToken on the flow selects the source token type. Without a transformation, that is also the type delivered to the target. A transformation can change it: for example, AddFlow<Order>("DisplayTotal", f => f.AddTransformation(async c => c.Token.Items.Sum(item => item.Price * item.Quantity))) delivers a decimal instead of an Order. The target must consume the transformed type. A guard that returns false prevents that token from traversing the flow.
Tokens are separate from control flow. Use AddControlFlow for sequencing without data. See Tokens, Flows, Input Pin, and Output Pin.
Activity node names are globally unique, including across nested scopes.
AddFlow<TToken>("name") resolves the registered name directly; if the target
is outside the source's containing scope, the flow crosses that boundary
automatically. Guards, transformations, weights, and implicit joins keep their
normal semantics.
Ordinary structured scopes allow both directions. Incoming offers wait for all destination scopes to start normally and cannot cross into reentrant structured scopes. Parallel/iterative boundaries allow outgoing crossings only to nodes directly in the immediately enclosing scope. Direct offers do not change output-pin aggregation or introduce interleaving. See Crossing structured boundaries for execution ownership and activation rules.
public sealed record Item(string Name, decimal Price, int Quantity);
public sealed record Order(string Id, IReadOnlyList<Item> Items);Home page Support Code licensed under an MIT-style License. Documentation licensed under CC BY 4.0. © by Mikołaj Milewski, 2026