Aurora.Workflows.Fluent 0.3.1.53

There is a newer version of this package available.
See the version list below for details.
dotnet add package Aurora.Workflows.Fluent --version 0.3.1.53
                    
NuGet\Install-Package Aurora.Workflows.Fluent -Version 0.3.1.53
                    
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="Aurora.Workflows.Fluent" Version="0.3.1.53" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Aurora.Workflows.Fluent" Version="0.3.1.53" />
                    
Directory.Packages.props
<PackageReference Include="Aurora.Workflows.Fluent" />
                    
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 Aurora.Workflows.Fluent --version 0.3.1.53
                    
#r "nuget: Aurora.Workflows.Fluent, 0.3.1.53"
                    
#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 Aurora.Workflows.Fluent@0.3.1.53
                    
#: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=Aurora.Workflows.Fluent&version=0.3.1.53
                    
Install as a Cake Addin
#tool nuget:?package=Aurora.Workflows.Fluent&version=0.3.1.53
                    
Install as a Cake Tool

Aurora.Workflows.Fluent

A self-documenting, modern Fluent API for building Aurora Workflows in C#.
Design complex automation pipelines with readable, chainable syntax – including branching, loops, scopes, parallel execution, and error handling.


Installation

dotnet add package Aurora.Workflows.Fluent

The package targets .NET Standard 2.0 and works with .NET Framework 4.6.1+, .NET 6/7/8, and .NET Core 3.1+.


Quick Start

using Aurora.Workflows.Fluent;
using Aurora.Workflows.Tasks;

var workflow = FluentWorkflow
    .Create("Hello World")
    .TriggerOnce()
    .Print("Hello, Aurora Workflows!")
    .Build();

await workflow.StartAsync();

Core Concepts

Concept Method Description
Create FluentWorkflow.Create("name") Entry point – creates a workflow with an implicit root StartTask
Trigger .TriggerOnce(), .TriggerPeriodic(), .TriggerOnSchedule() When the workflow runs
Sequential .Do<T>() / .Then.Do<T>() Adds a child task (runs after its parent)
Parallel .Parallel(…) / .AddBranch<T>() Adds sibling branches under the same parent
Condition .If(expr, then, else) Runtime if/else branching
Multi-way .Switch(sw => sw.Case(…).Default(…)) Multi-case runtime branching
Loop .Loop(expr, body) Repeat body while expression is true
Scope .Throttle(), .OnChange() Stateful execution scopes
Merge .Merge() AND-gate: wait for all parallel branches
Modifier .Named(), .WithInput(), .Retry(), … Configures the current task (returns this)
Terminal .Build(), .Commit() Finishes building

API by Category

1. Workflow Creation & Metadata

var builder = FluentWorkflow
    .Create("My Workflow", loggerFactory)   // required entry point
    .WithName("Renamed Workflow")           // override name
    .WithTags("etl", "nightly")             // classification tags
    .ConfigureWorkflow(wf => { … });        // raw IWorkflow access

2. Triggers

builder
    .TriggerOnce()                                        // run immediately, once
    .TriggerPeriodic(TimeSpan.FromMinutes(5))             // recurring
    .TriggerOnSchedule("0 2 * * *", "Nightly")           // cron
    .TriggerOnFileChange(@"C:\Inbox", "*.csv", "CSV In") // file watcher
    .AddTrigger<MyCustomTrigger>(t => t.Param = "x");    // custom trigger type

3. Adding Tasks – Sequential (Do / Then)

.Do<T>() adds a child task under the implicit root StartTask and returns a new builder scoped to it. .Then is syntactic sugar that makes chaining more readable. You never need to create a StartTask manually – it is provided automatically by Create().

FluentWorkflow.Create("demo")
    .TriggerOnce()

    .ReadFile("data.csv", outputVariable: "raw")

    .Then.Set("clean", "context.Get<string>(\"raw\").Trim()")

    .Then.Print("Done!", ConsoleColor.Green)

    .Build();

4. Task Shortcuts

Common tasks have one-liner convenience methods so you don't need Do<T>() with a lambda:

// Variables
.Set("counter", "0")                              // alias for SetVariable()
.SetVariable("total", "a + b")

// File I/O
.ReadFile("input.csv", outputVariable: "raw")      // auto-quotes the path
.WriteFile("output.csv", inputVariable: "data")    // auto-quotes the path
.WriteFile("log.txt", append: true)                // append mode

// Expression-based variants (path evaluated at runtime)
.ReadFileExpression("context.Get<string>(\"dynamicPath\")")
.WriteFileExpression("config.OutputPath")

// Console output
.Print("Hello!", ConsoleColor.Cyan)                // static text
.PrintExpression("$\"Count: {myVar}\"")             // runtime expression

// Pause
.Wait(TimeSpan.FromSeconds(5))

All shortcuts return the task builder, so modifiers like .Retry(), .Named(), etc. chain naturally.

5. Branching – Parallel Siblings

.Do<StartTask>(t => t.Name = "Fan-Out")
    .Parallel(
        new ReadFileTask { Expression = "\"a.csv\"", Name = "Read A" },
        new ReadFileTask { Expression = "\"b.csv\"", Name = "Read B" })

    .Merge("Wait for all")           // AND-gate synchronization

    .Then.Print("All branches done")

6. Conditions – If / Else

The expression is evaluated at runtime by the Roslyn evaluator.

.If("context.Get<int>(\"count\") > 0",
    then:  t => t.Print("Has items",  ConsoleColor.Green),
    @else: e => e.Print("Empty list", ConsoleColor.Red),
    name: "Check Count")

7. Multi-way Branching – Switch

Chains nested ConditionQueryTask nodes (if / else-if / else).

.Switch(sw => sw
    .Case("score >= 90", b => b.Print("A"))
    .Case("score >= 70", b => b.Print("B"))
    .Case("score >= 50", b => b.Print("C"))
    .Default(            b => b.Print("F")),
    name: "Grade")

8. Loops

.Loop("context.Get<int>(\"i\") < 10", body => body
    .Do<SetVariableTask>(t =>
    {
        t.Expression = "context.Get<int>(\"i\") + 1";
        t.CustomOutputVariableName = "i";
    })
        .UseGlobalScopeForInput()
        .UseGlobalScopeForOutput(),
    name: "Count to 10")

9. Scopes – Throttle & OnChange

// Execute at most once per hour
.Throttle(TimeSpan.FromHours(1), body => body
    .Print("Throttled action"))

// Execute only when the config file changes
.OnChange("System.IO.File.ReadAllText(\"config.json\")", body => body
    .Print("Config changed – reloading!"))

10. Task Modifiers

Modifiers configure the current task and return this (no new builder is created).

.ReadFile("data.txt", outputVariable: "outputVar", name: "Load Data")
    .WithInput("inputVar")                       // bind input variable
    .Retry(TimeSpan.FromSeconds(3), maxRetries: 5)
    .IgnoreErrors()                              // continue on failure
    .WithErrorHandling(continueOnError: true, retryCount: 3)
    .WithDelay(before: TimeSpan.FromSeconds(1))
    .UseGlobalScopeForOutput()                   // variable scoping
    .UseParentScopeForInput()
    .BreakOnDebug()                              // debugger support
    .SkipOnDebug()

11. Extension Methods

Higher-order helpers available via FluentWorkflowExtensions:

// Chain pre-built tasks sequentially
.Chain(task1, task2, task3)

// Repeat a task N times
.Repeat<DebugOutputTask>(5, (t, i) => t.Expression = $"\"#{i}\"")

// ForEach over a collection
.ForEach<ReadFileTask, string>(files, (t, f) => t.Expression = $"\"{f}\"")

// Named group (container StartTask)
.Group("Cleanup", g => g.Print("Cleaning…").Then.Do<GcTask>())

// Build-time conditional (NOT runtime!)
.When(isDebug, b => b.Print("Debug info"))
.DoIf<DebugOutputTask>(isDebug, t => t.Expression = "\"dbg\"")

// Parallel with typed tasks
.Parallel<WorkerTask>(4, (t, i) => t.Name = $"Worker {i}")

12. Execution

// Option A: Build, then execute
var wf = builder.Build();
await wf.StartAsync();

// Option B: Shortcut – execute directly from builder
var ctx = await builder.ExecuteAsync();

// Option C: Synchronous (blocking)
var ctx = builder.Execute();

// Long-running with triggers
await builder.StartAsync();
// ... later ...
await builder.StopAsync();

// Pause / Resume
var json = await builder.PauseAsync();
await builder.ResumeAsync(json);

Complete Example – ETL Pipeline

var workflow = FluentWorkflow
    .Create("Customer ETL", loggerFactory)
    .WithTags("ETL", "Production")
    .TriggerOnSchedule("0 3 * * *", "Nightly ETL")

    // ── Extract ──
    .Group("Extract", g => g
            .Do<ReadFileTask>(t =>
            {
                t.Expression = "\"customers.csv\"";
                t.Name = "Read CSV";
            })
                .WithOutput("rawData")
                .Retry(TimeSpan.FromSeconds(5), maxRetries: 3))

        // ── Transform (parallel) ──
        .Group("Transform", g => g
            .Async("Parallel Transform")
                .Parallel(
                    new SetVariableTask { Expression = "rawData.ToUpper()", CustomOutputVariableName = "upper" },
                    new SetVariableTask { Expression = "rawData.Trim()",    CustomOutputVariableName = "trim"  })
                .Merge("Await transforms"))

        // ── Load ──
        .Group("Load", g => g
            .Do<WriteFileTask>(t =>
            {
                t.Expression = "\"customers_out.csv\"";
            })
                .WithInput("upper")
            .Then.Print("ETL complete ✓", ConsoleColor.Green))

        .Build();

await workflow.StartAsync();

Migration from Legacy API

Legacy Modern Notes
AddTask<StartTask>() (implicit) Root StartTask is created automatically by Create()
AddChildTask<T>(…) Do<T>(…) Shorter, same behavior. Legacy alias kept.
SetInputVariable("x") WithInput("x") Alias kept.
SetOutputVariable("x") WithOutput("x") Alias kept.
Decide(expr, name, whenTrue, whenFalse) If(expr, then, else, name) Alias kept.
AddTaskIf<T>(cond, …) DoIf<T>(cond, …) Alias kept.
WithDelay(preDelay, postDelay) WithDelay(before, after) Param renamed.

All legacy method signatures are preserved as aliases – existing code continues to compile.


License

See LICENCE.MD in the package root. 6. Add Debug Output: Use Debug() and Print() during development 7. Configure Retry Logic: Add retry for network/external operations 8. Group Related Tasks: Use Group() to organize complex workflows

Migration from Old API

Old API:

var workflow = FluentWorkflow.Create("My Workflow");
var builder = workflow.SetupTasks();
builder.AddChildTask(new MyTask());
builder.SetOutputVariable("result");
var wf = builder.Commit().Get();

New API:

var workflow = FluentWorkflow
    .Create("My Workflow")
    .AddTask<MyTask>()
        .SetOutputVariable("result")
    .Build();

License

Copyright © Ben Wagner 2020+

See LICENCE.MD for details.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
0.4.1.2 110 3/16/2026
0.4.1.1 104 3/16/2026
0.3.1.60 105 3/14/2026
0.3.1.56 100 3/12/2026
0.3.1.55 97 3/12/2026
0.3.1.53 92 3/9/2026
0.3.1.52 94 3/5/2026
0.3.1.47 88 3/5/2026
0.3.1.46 88 3/5/2026
0.3.1.45 91 3/4/2026
0.3.1.40 87 3/4/2026
0.3.1.33 97 3/4/2026
0.3.1.26 90 3/3/2026
0.3.1.24 98 3/3/2026
0.3.1.9 96 3/2/2026
0.3.1.8 93 2/20/2026
0.3.1.7 93 2/20/2026
0.3.1.6 91 2/20/2026
0.3.1.5 98 2/19/2026
0.3.1.3 92 2/19/2026
Loading failed