LightFlowy 2.0.0
dotnet add package LightFlowy --version 2.0.0
NuGet\Install-Package LightFlowy -Version 2.0.0
<PackageReference Include="LightFlowy" Version="2.0.0" />
<PackageVersion Include="LightFlowy" Version="2.0.0" />
<PackageReference Include="LightFlowy" />
paket add LightFlowy --version 2.0.0
#r "nuget: LightFlowy, 2.0.0"
#:package LightFlowy@2.0.0
#addin nuget:?package=LightFlowy&version=2.0.0
#tool nuget:?package=LightFlowy&version=2.0.0
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
- Press F5 or click the green Continue button in the exception dialog.
- You’ll see that execution resumes and prints:
That proves the fallback executed correctly and the flow was not interrupted.input handled by fallback
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
- Press F5 or click the green Continue button in the exception dialog.
- You’ll see that execution resumes and prints:
That proves the RetryWorkflow executed correctly and the flow was not interrupted.payload succeeded
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
- Press F5 or click the green Continue button in the exception dialog.
- You’ll see that execution resumes and prints:
That proves the flow executed correctly and the it was not interrupted."Confirmation email sent" OR "Payment sent to manual review"
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:
| Product | Versions 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. |
-
net10.0
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.9)
- Microsoft.Extensions.Logging.Console (>= 10.0.9)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.