LightFlowy 2.0.0

dotnet add package LightFlowy --version 2.0.0
                    
NuGet\Install-Package LightFlowy -Version 2.0.0
                    
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="LightFlowy" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LightFlowy" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="LightFlowy" />
                    
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 LightFlowy --version 2.0.0
                    
#r "nuget: LightFlowy, 2.0.0"
                    
#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 LightFlowy@2.0.0
                    
#: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=LightFlowy&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=LightFlowy&version=2.0.0
                    
Install as a Cake Tool

LightFlowy

LightFlowy is a lightweight .NET package that provides orchestration patterns — plug in your logic and let LightFlowy handle the flow. Think of it as orchestration templates, not a workflow engine.

Why LightFlowy

  • LightFlowy is not a workflow engine — it’s a helper toolkit.
  • It provides ready-to-use orchestration patterns in a lightweight, developer-friendly way.
  • Developers can focus on business logic and plug their functions into templates, instead of learning a full orchestration DSL or engine.
  • Ideal for ASP.NET Core apps, microservices, and background jobs where you want orchestration but don’t need a full workflow runtime.

Orchestration Patterns

Orchestration is how we coordinate tasks so they work together effectively. Instead of one task doing everything, orchestration defines patterns of collaboration:

  • Sequential: Tasks run one after another, passing results forward like steps in a pipeline.
  • Parallel: Multiple tasks run at the same time, and their outputs are combined.
  • Fallback: If one task fails, another takes over as backup.
  • Retry: A task retries its execution until it succeeds or reaches a limit.
  • Composer: Lets you mix and match these patterns into more complex flows.

Why it’s useful:

  • ASP.NET Core apps (e.g., orchestrating services or pipelines).
  • Background jobs (e.g., retrying tasks, handling fallbacks).
  • Microservices (e.g., coordinating multiple service calls).

By using LightFlowy, you don’t need to design these orchestration patterns from scratch — you just plug them in and focus on your business logic.


Quick Start

This section shows how to install and run your first workflow in just a few lines of code.

1. Install the package

dotnet add package LightFlowy

2. Create a new Console App

dotnet new console -n WorkflowDemo
cd WorkflowDemo

3. Add a simple workflow in Program.cs


using LightFlowy;
using Microsoft.Extensions.Logging;

class Program
{
    static async Task Main(string[] args)
    {
        // Business logic functions
        async Task<string> Step1(string input, CancellationToken ct) 
            => input + " -> step1";

        async Task<string> Step2(string input, CancellationToken ct) 
            => input + " -> step2";

        // Run sequential workflow
        var result = await SequentialWorkflow.RunAsync(
            "start",
            CancellationToken.None,
            null,  //optional logger, LightFlowy can create one internally if null
            Step1,
            Step2
        );

        Console.WriteLine(result);        
    }
}

4. Run the demo

dotnet run

// Output: "start → step1 → step2"


What you learned

  • You installed LightFlowy.
  • You created a SequentialWorkflow with two steps.
  • You saw how orchestration logic is handled by the library, while you only write your business logic.

Logging

LightFlowy supports optional logging through ILogger. Developers can plug in their own logging provider (e.g., Serilog, NLog, Application Insights) or let LightFlowy create a default console logger if none is provided. This flexibility allows you to capture retries, fallbacks, and exceptions in the format and destination that best fit your application.


using LightFlowy;
using Microsoft.Extensions.Logging;

class Program
{
    static async Task Main(string[] args)
    {
        // Example: injecting a custom logger
        var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
        var logger = loggerFactory.CreateLogger<Program>();

        var result = await RetryWorkflow.RunWithRetryAsync(
            "payload",
            async (input, ct) =>
            {
                if (new Random().Next(0, 2) == 0) throw new Exception("Random failure");
                return input + " succeeded";
            },
            maxRetries: 3,
            cancellationToken: CancellationToken.None,
            logger: logger // custom logger injected here
        );

        Console.WriteLine(result);
    }
}

Examples (by Workflow)

1. SequentialWorkflow

Run tasks one after another, passing the result forward.

The SequentialWorkflow will accept as many steps as you indicate, and each step is just an async function that receives the previous output and a CancellationToken.


//Program.cs:

using LightFlowy;

var result = await SequentialWorkflow.RunAsync(
    "start",
    CancellationToken.None,
    null,  //optional logger, LightFlowy can create one internally if null
    async (input, ct) => input + " -> step1",
    async (input, ct) => input + " -> step2"
);

Console.WriteLine(result);  

// Output = "start -> step1 -> step2"


2. ParallelWorkflow

Run tasks concurrently and collect all results.

You can pass in as many tasks as you need, and LightFlowy will execute them all in parallel, returning their outputs together.


//Program.cs:

using LightFlowy;

var results = await ParallelWorkflow.RunAsync(
    "data",
    CancellationToken.None,
    null,  //optional logger, LightFlowy can create one internally if null
    async (input, ct) => input + " processed by A",
    async (input, ct) => input + " processed by B"
);

Console.WriteLine(string.Join(", ", results));  

// results = ["data processed by A", "data processed by B"]


3. FallbackWorkflow

If one step fails, the next one is attempted.

You can chain multiple fallback options, ensuring that if one fails, the next backup takes over until success.


//Program.cs:

using LightFlowy;

var result = await FallbackWorkflow.RunAsync(
    "input",
    CancellationToken.None,
    null,  //optional logger, LightFlowy can create one internally if null
    async (input, ct) => throw new Exception("Step1 failed"),
    async (input, ct) => input + " handled by fallback"
);

Console.WriteLine(result);  

// Output = "input handled by fallback"

How to confirm the flow is still working despite the thrown exception

  1. Press F5 or click the green Continue button in the exception dialog.
  2. You’ll see that execution resumes and prints:
    input handled by fallback
    
    That proves the fallback executed correctly and the flow was not interrupted.

4. RetryWorkflow

Retry a step multiple times with logging.

You can configure the number of retries, add logging, and even combine it with fallback for maximum resilience.


//Program.cs:

using LightFlowy;
using Microsoft.Extensions.Logging;

var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
var logger = loggerFactory.CreateLogger<Program>();

var result = await RetryWorkflow.RunWithRetryAsync(
    "payload",
    async (input, ct) =>
    {
        if (new Random().Next(0, 2) == 0) throw new Exception("Random failure");
        return input + " succeeded";
    },
    maxRetries: 3,    
    cancellationToken: CancellationToken.None,
	logger: logger
);

Console.WriteLine(result);  

// Output = "payload succeeded"

How to confirm the flow is still working despite the thrown exception

  1. Press F5 or click the green Continue button in the exception dialog.
  2. You’ll see that execution resumes and prints:
    payload succeeded
    
    That proves the RetryWorkflow executed correctly and the flow was not interrupted.

5. WorkflowComposer

Combine multiple workflows into a single flow.

This is the most flexible orchestration pattern: you can mix sequential, parallel, retry, and fallback strategies into one composite workflow.


//Program.cs:

using LightFlowy;

var result = await WorkflowComposer.ComposeAsync(
    "start",
    CancellationToken.None,
    null,  //optional logger, LightFlowy can create one internally if null
    async (input, ct) => await SequentialWorkflow.RunAsync(
        input, ct,
        null,  //optional logger, LightFlowy can create one internally if null
        async (input, ct) => input + " -> step1",
        async (input, ct) => input + " -> step2"
    ),
    async (input, ct) => (await ParallelWorkflow.RunAsync(
        input, ct,
        null,  //optional logger, LightFlowy can create one internally if null
        async (input, ct) => input + " parallel A",
        async (input, ct) => input + " parallel B"
    )).First()
);

Console.WriteLine(result);  

// Output = "start -> step1 -> step2 parallel A"


Advanced (Resilient Workflow)

Imagine you need to process an order with these steps:

  • Validate the order.
  • Charge the payment.
  • Send a confirmation email.
  • If payment fails, retry or fallback to manual review.

Without LightFlowy, you’d have to write all the orchestration logic yourself (loops, try/catch, parallel tasks, retries). With the package, you just plug in your business logic functions into the templates:


//Program.cs:

using LightFlowy;
using Microsoft.Extensions.Logging;

class Program
{
    static async Task Main(string[] args)
    {
        var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
        var logger = loggerFactory.CreateLogger<Program>();

        // Business logic functions
        async Task<string> ValidateOrder(string input, CancellationToken ct)
            => "Order validated";

        async Task<string> ChargePayment(string input, CancellationToken ct)
        {
            if (new Random().Next(0, 2) == 0) throw new Exception("Payment failed");
            return "Payment successful";
        }

        async Task<string> ManualReview(string input, CancellationToken ct)
            => "Payment sent to manual review";

        async Task<string> SendConfirmation(string input, CancellationToken ct)
            => "Confirmation email sent";

        // Resilient workflow: Sequential + Retry + Fallback
        var result = await SequentialWorkflow.RunAsync(
          "Start",
          CancellationToken.None,
          null,  //optional logger, LightFlowy can create one internally if null
          ValidateOrder,
          async (input, ct) => await FallbackWorkflow.RunAsync(
              input, ct,
              null,  //optional logger, LightFlowy can create one internally if null
              async (input, ct) => await RetryWorkflow.RunWithRetryAsync(
                  input, ChargePayment, maxRetries: 3, ct, logger),
              ManualReview
          ),
          SendConfirmation
      );

        Console.WriteLine(result);
    }
}


// Output: "Confirmation email sent" OR "Payment sent to manual review"

How it works

  • SequentialWorkflow ensures steps run in order: validate --> payment --> confirmation.
  • RetryWorkflow retries the payment step up to 3 times before failing.
  • FallbackWorkflow catches failures and routes to manual review.
  • The orchestration logic is handled by LightFlowy, while you only write the business logic functions.

How to confirm the flow is still working despite the thrown exception

  1. Press F5 or click the green Continue button in the exception dialog.
  2. You’ll see that execution resumes and prints:
    "Confirmation email sent" OR "Payment sent to manual review"
    
    That proves the flow executed correctly and the it was not interrupted.

Key Benefits

  • Resilience: Instead of failing once and crashing, algorithms can be retried automatically or redirected to a fallback task.
  • Consistency: Processes enforce a predictable order (sequential, parallel, etc.), so outputs are reliable across runs.
  • Separation of concerns: You focus on writing the algorithm’s logic (summarizer, search, formatter), while LightFlowy handles orchestration, retries, and error handling.
  • Scalability: Multiple agents can run in parallel or be composed into larger workflows, making it easier to scale complex systems.
  • Maintainability: Instead of scattering try/catch blocks and loops across your code, orchestration patterns centralize error handling and flow control.
  • Flexibility: You can swap agents in and out (e.g., replace OpenAI with Azure OpenAI) without redesigning the orchestration logic.

Quick Reference Table

Workflow Purpose Best Use Case Error Handling
SequentialWorkflow Run tasks one after another, passing results forward Pipelines, ordered steps (e.g., validation → processing → storage) Fails immediately if a step throws (logging supported)
ParallelWorkflow Run tasks concurrently and collect all outputs API calls, batch jobs, independent tasks Any failed task propagates exception (logging supported)
FallbackWorkflow Provide backup if one step fails Resilient workflows, failover strategies Tries next fallback step if one fails (logging supported)
RetryWorkflow Retry failed tasks with logging until success or limit Unstable external services, transient errors Retries until success or max retries reached (logging supported)
WorkflowComposer Combine multiple workflows into a single flow Complex orchestration mixing sequential, parallel, and fallback Inherits error handling of composed workflows (logging supported)

⚖️ License

This project is freely available under the MIT license.
You may use it without restrictions, as long as you retain the reference to the original license.


Support the Project

If you find this library useful, consider supporting its development:

Buy Me a Coffee

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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
2.0.0 115 7/2/2026
1.0.9 105 7/1/2026
1.0.8 104 7/1/2026
1.0.7 112 7/1/2026
1.0.6 101 7/1/2026
1.0.5 108 7/1/2026
1.0.4 106 7/1/2026
1.0.3 104 7/1/2026
1.0.2 98 7/1/2026
1.0.1 113 7/1/2026
1.0.0 109 7/1/2026