WorkflowForge 2.1.2
dotnet add package WorkflowForge --version 2.1.2
NuGet\Install-Package WorkflowForge -Version 2.1.2
<PackageReference Include="WorkflowForge" Version="2.1.2" />
<PackageVersion Include="WorkflowForge" Version="2.1.2" />
<PackageReference Include="WorkflowForge" />
paket add WorkflowForge --version 2.1.2
#r "nuget: WorkflowForge, 2.1.2"
#:package WorkflowForge@2.1.2
#addin nuget:?package=WorkflowForge&version=2.1.2
#tool nuget:?package=WorkflowForge&version=2.1.2
WorkflowForge Core
Zero-dependency workflow orchestration framework for .NET
Overview
Foundational orchestration with zero external NuGet dependencies and the forge / foundry / smith metaphor: fast runs, saga-style compensation, middleware you control.
- Zero deps + platform: no extra packages; .NET Standard 2.0 (.NET Framework 4.6.1+, .NET Core 2.0+, .NET 5+)
- Speed, flow, builder: sub-20μs ops when tuned; thread-safe
foundry.Properties;CreateWorkflow(...).AddOperation(...).Build() - Saga, middleware, contracts, events:
RestoreAsync; Russian Doll middleware; optionalIWorkflowOperation<TIn, TOut>andEnableOutputChaining; lifecycle hooks
Quick start
dotnet add package WorkflowForge # .NET Standard 2.0+
Inline delegates: Operations.
using WorkflowForge;
using WorkflowForge.Extensions;
// Create workflow
var workflow = WorkflowForge.CreateWorkflow("OrderProcessing")
.AddOperation(new ValidateOrderOperation())
.AddOperation(new ChargePaymentOperation())
.AddOperation(new ReserveInventoryOperation())
.AddOperation(new CreateShipmentOperation())
.Build();
// Create execution environment
using var foundry = WorkflowForge.CreateFoundry("Order-12345");
foundry.SetProperty("OrderId", "12345");
foundry.SetProperty("CustomerId", "CUST-001");
// Execute workflow
using var smith = WorkflowForge.CreateSmith();
await smith.ForgeAsync(workflow, foundry);
// Read results
var shipmentId = foundry.GetPropertyOrDefault<string>("ShipmentId");
Architecture
Forge creates runtime pieces. Foundry (IWorkflowFoundry) holds context; Smith (IWorkflowSmith) runs the workflow; each operation (IWorkflowOperation) is one step, with shared data in foundry.Properties. Interface sources: IWorkflowFoundry · IWorkflowSmith · IWorkflowOperation
Built-in operations (guide)
- DelegateWorkflowOperation: delegate/lambda steps
- ActionWorkflowOperation: action-style steps
- ConditionalWorkflowOperation: branch on foundry state
- ForEachWorkflowOperation: collections, concurrency caps
- DelayOperation:
TimeSpanwait - LoggingOperation: fixed log line
Custom operations
Subclass WorkflowOperationBase, override ForgeAsyncCore; add RestoreAsync when you need compensation. Typed bases: Operations.
public class CalculateTotalOperation : WorkflowOperationBase
{
public override string Name => "CalculateTotal";
protected override async Task<object?> ForgeAsyncCore(
object? inputData,
IWorkflowFoundry foundry,
CancellationToken cancellationToken = default)
{
var items = foundry.GetPropertyOrDefault<List<OrderItem>>("Items");
var total = items.Sum(x => x.Price * x.Quantity);
foundry.SetProperty("Total", total);
foundry.Logger.LogInformation("Calculated total: {Total}", total);
return total;
}
}
Compensation (saga pattern)
public class ChargePaymentOperation : WorkflowOperationBase
{
public override string Name => "ChargePayment";
protected override async Task<object?> ForgeAsyncCore(
object? inputData,
IWorkflowFoundry foundry,
CancellationToken cancellationToken)
{
var orderId = foundry.GetPropertyOrDefault<string>("OrderId");
var amount = foundry.GetPropertyOrDefault<decimal>("Total");
var paymentId = await _paymentService.ChargeAsync(orderId, amount, cancellationToken);
foundry.SetProperty("PaymentId", paymentId);
foundry.Logger.LogInformation("Payment charged: {PaymentId}", paymentId);
return paymentId;
}
public override async Task RestoreAsync(
object? outputData,
IWorkflowFoundry foundry,
CancellationToken cancellationToken)
{
var paymentId = foundry.GetPropertyOrDefault<string>("PaymentId");
if (!string.IsNullOrEmpty(paymentId))
{
await _paymentService.RefundAsync(paymentId, cancellationToken);
foundry.Logger.LogInformation("Payment refunded: {PaymentId}", paymentId);
}
}
}
Middleware
foundry.UseTiming();
foundry.UseErrorHandling(rethrowExceptions: true);
Custom IWorkflowOperationMiddleware: Architecture · Operations
Event system
- Smith:
WorkflowStarted,WorkflowCompleted,WorkflowFailed,CompensationTriggered,OperationRestoreStarted, and related compensation hooks - Foundry:
OperationStarted,OperationCompleted,OperationFailed
Configuration
WorkflowForgeOptions extends WorkflowForgeOptionsBase (Enabled, SectionName, Validate(), Clone()). Bind JSON with WorkflowForge.Extensions.DependencyInjection. Configuration.
Programmatic:
var options = new WorkflowForgeOptions
{
Enabled = true,
MaxConcurrentWorkflows = 10,
ContinueOnError = false,
FailFastCompensation = false,
ThrowOnCompensationError = true,
EnableOutputChaining = true
};
var foundry = WorkflowForge.CreateFoundry("MyWorkflow", options: options);
appsettings.json:
{
"WorkflowForge": {
"Enabled": true,
"MaxConcurrentWorkflows": 10,
"ContinueOnError": false,
"FailFastCompensation": false,
"ThrowOnCompensationError": true,
"EnableOutputChaining": true
}
}
Performance
12 scenarios (50 iterations each) vs Workflow Core and Elsa: 13–511× execution, 6–575× allocation, up to 511× (.NET 10.0 state machine), ~15.9× at 16 concurrent workflows.
| Scenario | WorkflowForge | Workflow Core | Elsa | Advantage |
|---|---|---|---|---|
| Sequential (10 ops) | 314μs | 15,997μs | 26,881μs | 51–86× |
| State machine (25) | 111μs | 39,500μs | 45,714μs | 356–412× |
| Concurrent (8 workers) | 482μs | 59,141μs | 137,342μs | 123–285× |
Benchmark data from .NET 8.0; up to 511× on .NET 10.0 (state machine). All scenarios.
Documentation
- Getting started · Samples (33)
- Architecture · Operations · Events · Configuration
- Extensions · API reference · WorkflowForge.Testing (
FakeWorkflowFoundry)
Extensions
- WorkflowForge.Testing:
FakeWorkflowFoundryand helpers - WorkflowForge.Extensions.Logging.Serilog: structured logging
- WorkflowForge.Extensions.Resilience: retry (no extra deps)
- WorkflowForge.Extensions.Resilience.Polly: Polly-based resilience
- WorkflowForge.Extensions.Validation: DataAnnotations validation
- WorkflowForge.Extensions.Audit: audit logging
- WorkflowForge.Extensions.Persistence: workflow state persistence
- WorkflowForge.Extensions.Persistence.Recovery: recovery coordinator
- WorkflowForge.Extensions.Observability.Performance: performance hooks
- WorkflowForge.Extensions.Observability.HealthChecks: health checks
- WorkflowForge.Extensions.Observability.OpenTelemetry: tracing
Third-party assemblies are often merged with ILRepack; Microsoft/runtime refs stay external. License: MIT (LICENSE).
| Product | Versions 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. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages (11)
Showing the top 5 NuGet packages that depend on WorkflowForge:
| Package | Downloads |
|---|---|
|
WorkflowForge.Extensions.Resilience
Resilience and retry extension for WorkflowForge workflow engine. Provides circuit breakers, retry strategies, and timeout management for robust workflow execution. |
|
|
WorkflowForge.Extensions.Logging.Serilog
Serilog adapter for WorkflowForge providing professional structured logging capabilities with rich context and correlation. |
|
|
WorkflowForge.Extensions.Observability.Performance
Performance monitoring and profiling extension for WorkflowForge providing detailed metrics, execution timing, memory usage tracking, and performance optimization insights for production workflows. |
|
|
WorkflowForge.Extensions.Observability.HealthChecks
Health monitoring and diagnostics extension for WorkflowForge providing comprehensive health checks, dependency monitoring, and system status reporting for production workflows. |
|
|
WorkflowForge.Extensions.Observability.OpenTelemetry
OpenTelemetry integration for WorkflowForge providing distributed tracing, metrics collection, and observability instrumentation for comprehensive workflow monitoring and debugging. |
GitHub repositories
This package is not used by any popular GitHub repositories.
v2.1.2: Fixed ILRepacked extensions (Polly, OpenTelemetry, Serilog) that were missing transitive dependencies and threw a runtime FileNotFoundException (e.g. Microsoft.Bcl.TimeProvider) — the required BCL/Microsoft.Extensions packages now flow to consumers. Implemented foundry performance monitoring so EnablePerformanceMonitoring()/GetPerformanceStatistics() work end-to-end. Fixed pooled-foundry state leaking across executions and audit entries recording "Unknown" workflow names. Centralized package versioning and shared metadata. Hardened lifecycle-event exception isolation and smith disposal.