ReactiveDAG 1.1.1

dotnet add package ReactiveDAG --version 1.1.1
                    
NuGet\Install-Package ReactiveDAG -Version 1.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ReactiveDAG" Version="1.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ReactiveDAG" Version="1.1.1" />
                    
Directory.Packages.props
<PackageReference Include="ReactiveDAG" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ReactiveDAG --version 1.1.1
                    
#r "nuget: ReactiveDAG, 1.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ReactiveDAG@1.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ReactiveDAG&version=1.1.1
                    
Install as a Cake Addin
#tool nuget:?package=ReactiveDAG&version=1.1.1
                    
Install as a Cake Tool

ReactiveDAG

A reactive DAG engine for .NET 8. You define inputs and computations, wire them together, and changes propagate through the graph automatically.

Good for simulations, multi-step calculations where intermediate results get reused, build/task orchestration, or anywhere you'd reach for a spreadsheet-like dependency model.

Architecture

There are two ways to use this:

DagPipelineBuilder — fluent API for building pipelines. You chain .AddInput().AddFunction() and it tracks the wiring for you. Best for straightforward linear/fan-in pipelines.

DagEngine — the underlying engine. Use it directly when you need explicit dependency arrays, node removal, streaming, or want to inspect the graph at runtime.

Under the hood, Cell<T> holds a value and DagNode<T> wraps it with computation logic. When an input changes, the engine walks dependents and recomputes what's needed.

Components

  • DagEngine — manages nodes, propagates updates, detects cycles, handles concurrency
  • DagPipelineBuilder — fluent builder on top of DagEngine
  • Cell<T> — input cells hold values directly; function cells get their values from a compute function
  • DagNode<T> — wraps a cell, tracks dependencies, handles lazy/on-demand computation

API Reference

Creating Inputs

// Via builder
builder.AddInput(42, out Cell<int> cell);

// Via engine directly
Cell<int> cell = engine.AddInput(42);

Adding Functions

// All inputs share a type
builder.AddFunction<int, int>(async inputs => inputs.Sum(), out var sum);

// Mixed types — pass explicit BaseCell[] dependencies
engine.AddFunction<string>(
    new BaseCell[] { intCell, dateCell },
    async inputs => $"{inputs[0]} on {inputs[1]}");

// Explicit typed dependencies
engine.AddFunction<int, int>(new[] { a, b }, async inputs => inputs[0] + inputs[1]);

Updating Inputs

await engine.UpdateInput(cell, newValue);

This triggers recomputation of everything downstream.

Getting Results

var value = await engine.GetResult(cell);

Streaming

Subscribe to a cell's value over time:

await foreach (var value in engine.StreamResults(cell, cancellationToken))
{
    Console.WriteLine(value);
}

Yields the current value first, then emits whenever the cell recomputes.

Inspecting the Graph

int count = engine.NodeCount;

foreach (var node in engine.GetAllNodes())
{
    var cell = node.GetCell();
    var deps = node.GetDependencies();
    var value = await node.EvaluateAsync();
}

bool changed = engine.HasChanged(myCell);

Removing Nodes

engine.RemoveNode(cell);

Combining Mixed-Type Cells

Cell<object[]> combined = builder.CombineCells(intCell, stringCell, boolCell);

Execution Model

  • All compute functions are async (Func<T[], Task<TResult>>).
  • UpdateInput walks dependents in topological order and recomputes them.
  • Multiple inputs to a function node resolve concurrently (Task.WhenAll).
  • If a node recomputes to the same value, propagation stops there (uses EqualityComparer<T>.Default).
  • AddFunction checks for cycles immediately and rolls back if one would form.
  • Thread-safe: atomic index generation, per-node compute locks, global semaphore for propagation.

Use Cases

  • Backend orchestration: API request pipelines, service dependencies, event-driven workflows
  • Financial calculations: risk analysis, transaction chains, dynamic pricing
  • Simulations with inputs that change over time

How it Works

  1. Create input cells with initial values.
  2. Add function cells that depend on those inputs (or on other function cells).
  3. Call UpdateInput when something changes.
  4. The engine recomputes everything downstream automatically.

Examples

Please go to the Git repo for examples.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.1 116 7/10/2026
1.1.0 149 2/13/2026
1.0.9 178 12/12/2025
1.0.8 184 9/27/2025
1.0.7 212 7/28/2025
1.0.6 165 5/24/2025
1.0.5 267 5/21/2025
1.0.4 256 5/21/2025
1.0.3 237 2/6/2025
1.0.2 207 1/20/2025
1.0.0 191 1/15/2025