WorkflowForge 1.0.0
See the version list below for details.
dotnet add package WorkflowForge --version 1.0.0
NuGet\Install-Package WorkflowForge -Version 1.0.0
<PackageReference Include="WorkflowForge" Version="1.0.0" />
<PackageVersion Include="WorkflowForge" Version="1.0.0" />
<PackageReference Include="WorkflowForge" />
paket add WorkflowForge --version 1.0.0
#r "nuget: WorkflowForge, 1.0.0"
#:package WorkflowForge@1.0.0
#addin nuget:?package=WorkflowForge&version=1.0.0
#tool nuget:?package=WorkflowForge&version=1.0.0
WorkflowForge Core
The foundational workflow orchestration framework for .NET with zero dependencies, built-in compensation, and sub-20 microsecond operation performance.
๐ฏ Core Package Overview
WorkflowForge Core is the dependency-free foundation of the WorkflowForge ecosystem, providing:
- ๐ญ Foundry & Smith Architecture: Industrial-strength metaphor with
IWorkflowFoundryfor execution context andIWorkflowSmithfor orchestration - โ๏ธ Flexible Operations: Support for sync/async operations, lambda expressions, and typed operations
- ๐ Compensation Support: Built-in saga pattern with automatic rollback capabilities
- ๐งฉ Middleware Pipeline: Extensible middleware system for cross-cutting concerns
- ๐ Data Management: Thread-safe shared data with
ConcurrentDictionary - ๐๏ธ Builder Pattern: Fluent API for constructing workflows
- ๐ง Zero Dependencies: Core framework has no external dependencies
- ๐ Multiple Execution Patterns: Sequential, parallel, conditional, and for-each operations
- ๐ฏ Type Safety: Strongly-typed operations with compile-time validation
- โก High Performance: Optimized for production workloads
๐ฆ Installation
dotnet add package WorkflowForge
๐ Quick Start
Create and Execute a Simple Workflow
using WorkflowForge;
// Create a workflow using the forge
var workflow = WorkflowForge.CreateWorkflow()
.WithName("ProcessOrder")
.AddOperation("ValidateOrder", async (order, foundry, ct) =>
{
foundry.Logger.LogInformation("Validating order {OrderId}", order.Id);
if (order.Amount <= 0)
throw new InvalidOperationException("Invalid order amount");
return order;
})
.AddOperation("ProcessPayment", async (order, foundry, ct) =>
{
foundry.Logger.LogInformation("Processing payment for order {OrderId}", order.Id);
var paymentResult = await ProcessPaymentAsync(order, ct);
foundry.Properties["PaymentId"] = paymentResult.Id;
return paymentResult;
})
.Build();
// Execute the workflow
using var foundry = WorkflowForge.CreateFoundry("ProcessOrder");
using var smith = WorkflowForge.CreateSmith();
try
{
var order = new Order { Id = "ORD-001", Amount = 99.99m };
foundry.Properties["order"] = order;
await smith.ForgeAsync(workflow, foundry);
foundry.Logger.LogInformation("Workflow completed successfully!");
}
catch (Exception ex)
{
foundry.Logger.LogError(ex, "Workflow execution failed");
}
๐ Interactive Learning & Examples
The fastest way to learn WorkflowForge is through our comprehensive interactive samples:
๐ฏ Complete Sample Collection
Interactive console application with 18 hands-on examples:
- Basic Workflows (1-4): Hello World, Data Passing, Multiple Outcomes, Inline Operations
- Control Flow (5-8): Conditional Workflows, ForEach Loops, Error Handling, Built-in Operations
- Configuration & Middleware (9-12): Options Pattern, Configuration Profiles, Workflow Events, Middleware Usage
- Extensions (13-17): Serilog Logging, Polly Resilience, OpenTelemetry, Health Checks, Performance Monitoring
- Advanced (18): Comprehensive Demo with all extensions
cd src/samples/WorkflowForge.Samples.BasicConsole
dotnet run
๐๏ธ Core Architecture
The WorkflowForge Metaphor
In the WorkflowForge metaphor:
- The Forge (
WorkflowForgestatic class) - Main factory for creating workflows and components - Foundries (
IWorkflowFoundry) - Execution environments where operations are performed - Smiths (
IWorkflowSmith) - Skilled craftsmen who manage foundries and forge workflows - Operations (
IWorkflowOperation) - Individual tasks performed in the foundry - Workflows (
IWorkflow) - Complete workflow definitions with operations
Core Abstractions
IWorkflowFoundry - Execution Environment
The foundry provides the execution context and shared resources:
public interface IWorkflowFoundry : IDisposable
{
Guid ExecutionId { get; }
IWorkflow? CurrentWorkflow { get; }
ConcurrentDictionary<string, object?> Properties { get; }
IWorkflowForgeLogger Logger { get; }
IServiceProvider? ServiceProvider { get; }
void SetCurrentWorkflow(IWorkflow? workflow);
void AddOperation(IWorkflowOperation operation);
}
IWorkflowSmith - Orchestration Engine
The smith manages workflow execution and compensation:
public interface IWorkflowSmith : IDisposable
{
Task ForgeAsync(IWorkflow workflow, IWorkflowFoundry foundry, CancellationToken cancellationToken = default);
Task ForgeAsync(IWorkflow workflow, ConcurrentDictionary<string, object?> data, CancellationToken cancellationToken = default);
// Additional overloads for various scenarios
}
IWorkflowOperation - Individual Tasks
Operations are the building blocks of workflows:
public interface IWorkflowOperation : IDisposable
{
Guid Id { get; }
string Name { get; }
bool SupportsRestore { get; }
Task<object?> ForgeAsync(object? inputData, IWorkflowFoundry foundry, CancellationToken cancellationToken);
Task RestoreAsync(object? outputData, IWorkflowFoundry foundry, CancellationToken cancellationToken);
}
๐ง Built-in Operations
Delegate Operations
Execute lambda expressions or method references:
// Simple synchronous operation
workflow.AddOperation("LogMessage", (input, foundry, ct) =>
{
foundry.Logger.LogInformation("Processing: {Input}", input);
return input;
});
// Asynchronous operation
workflow.AddOperation("ProcessAsync", async (input, foundry, ct) =>
{
await Task.Delay(100, ct);
return $"Processed: {input}";
});
Action Operations
Execute actions without return values:
var actionOp = new ActionWorkflowOperation("LogAction", (input, foundry, ct) =>
{
foundry.Logger.LogInformation("Action executed with: {Input}", input);
});
workflow.AddOperation(actionOp);
Conditional Operations
Execute operations based on conditions:
var conditionalOp = ConditionalWorkflowOperation.Create(
condition: foundry => foundry.Properties.ContainsKey("IsPremium"),
trueOperation: new PremiumProcessingOperation(),
falseOperation: new StandardProcessingOperation()
);
workflow.AddOperation(conditionalOp);
ForEach Operations
Process collections in parallel or sequentially:
var forEachOp = ForEachWorkflowOperation.Create<string>(
items: new[] { "item1", "item2", "item3" },
operation: new ProcessItemOperation(),
parallelExecution: true
);
workflow.AddOperation(forEachOp);
Utility Operations
Common utility operations:
// Delay operation
workflow.AddOperation(new DelayOperation(TimeSpan.FromSeconds(5)));
// Logging operation
workflow.AddOperation(new LoggingOperation("Processing started", LogLevel.Information));
๐ Compensation & Saga Pattern
WorkflowForge supports automatic compensation for saga patterns:
public class PaymentOperation : IWorkflowOperation
{
public string Name => "ProcessPayment";
public bool SupportsRestore => true;
public async Task<object?> ForgeAsync(object? inputData, IWorkflowFoundry foundry, CancellationToken cancellationToken)
{
var order = (Order)inputData!;
foundry.Logger.LogInformation("Processing payment for order {OrderId}", order.Id);
var paymentResult = await ProcessPaymentAsync(order, cancellationToken);
foundry.Properties["PaymentId"] = paymentResult.PaymentId;
return paymentResult;
}
public async Task RestoreAsync(object? outputData, IWorkflowFoundry foundry, CancellationToken cancellationToken)
{
if (foundry.Properties.TryGetValue("PaymentId", out var paymentId))
{
foundry.Logger.LogWarning("Reversing payment {PaymentId}", paymentId);
await RefundPaymentAsync((string)paymentId!, cancellationToken);
}
}
}
๐ Middleware System
Create custom middleware for cross-cutting concerns:
public class TimingMiddleware : IWorkflowMiddleware
{
private readonly IWorkflowForgeLogger _logger;
public TimingMiddleware(IWorkflowForgeLogger logger)
{
_logger = logger;
}
public async Task<object?> ExecuteAsync(IWorkflowOperation operation, object? inputData, IWorkflowFoundry foundry, Func<Task<object?>> next, CancellationToken cancellationToken)
{
var stopwatch = Stopwatch.StartNew();
try
{
var result = await next();
stopwatch.Stop();
_logger.LogInformation("Operation {OperationName} completed in {Duration}ms",
operation.Name, stopwatch.ElapsedMilliseconds);
return result;
}
catch (Exception ex)
{
stopwatch.Stop();
_logger.LogError(ex, "Operation {OperationName} failed after {Duration}ms",
operation.Name, stopwatch.ElapsedMilliseconds);
throw;
}
}
}
โ๏ธ Configuration
Foundry Configuration
Configure foundries for different environments:
// Minimal configuration
var foundry = WorkflowForge.CreateFoundry("MyWorkflow", FoundryConfiguration.Minimal());
// Development configuration
var foundry = WorkflowForge.CreateFoundry("MyWorkflow", FoundryConfiguration.ForDevelopment());
// Production configuration
var foundry = WorkflowForge.CreateFoundry("MyWorkflow", FoundryConfiguration.ForProduction());
// Custom configuration
var config = new FoundryConfiguration
{
EnableAutoRestore = true,
MaxConcurrentOperations = 8,
DefaultTimeout = TimeSpan.FromMinutes(5)
};
var foundry = WorkflowForge.CreateFoundry("MyWorkflow", config);
Workflow Settings
Configure workflows with metadata:
var workflow = WorkflowForge.CreateWorkflow()
.WithName("ProcessOrder")
.WithVersion("1.2.0")
.WithDescription("Process customer orders with payment and fulfillment")
.WithTimeout(TimeSpan.FromMinutes(10))
.AddOperation(/* operations */)
.Build();
๐งช Testing Support
WorkflowForge is designed for testability:
[Test]
public async Task Should_Execute_Workflow_Operations()
{
// Arrange
var mockOperation = new Mock<IWorkflowOperation>();
mockOperation.Setup(x => x.ForgeAsync(It.IsAny<object>(), It.IsAny<IWorkflowFoundry>(), It.IsAny<CancellationToken>()))
.ReturnsAsync("test-result");
var workflow = WorkflowForge.CreateWorkflow("TestWorkflow")
.AddOperation(mockOperation.Object)
.Build();
var foundry = WorkflowForge.CreateFoundry("TestWorkflow");
var smith = WorkflowForge.CreateSmith();
// Act
foundry.Properties["test-input"] = "test-input"; // Set input data in foundry
await smith.ForgeAsync(workflow, foundry);
// Assert
Assert.That(foundry.Properties["test-input"], Is.EqualTo("test-input"));
mockOperation.Verify(x => x.ForgeAsync(It.IsAny<object>(), foundry, It.IsAny<CancellationToken>()), Times.Once);
}
๐ Performance Characteristics
WorkflowForge Core delivers exceptional performance:
- Zero external dependencies - No additional overhead
- Sub-20 microsecond operations - Custom operations execute in 4-56 ฮผs
- 15x better concurrency scaling - 16 concurrent workflows vs sequential execution
- Minimal allocations - Efficient memory usage in hot paths
- Thread-safe operations - ConcurrentDictionary for shared state
๐ Extension Ecosystem
The core package integrates seamlessly with WorkflowForge extensions:
- WorkflowForge.Extensions.Logging.Serilog - Structured logging with Serilog
- WorkflowForge.Extensions.Resilience.Polly - Advanced resilience with Polly
- WorkflowForge.Extensions.Observability.OpenTelemetry - Distributed tracing
- WorkflowForge.Extensions.Observability.Performance - Performance monitoring
- WorkflowForge.Extensions.Observability.HealthChecks - System health monitoring
๐ Additional Resources
- Interactive Samples - Learn by example with 18 hands-on tutorials
- Performance Benchmarks - Verified performance claims
- Main Project Documentation - Framework overview
- Extension Documentation - Available extensions
๐ Professional Logging System
WorkflowForge Core includes a comprehensive, professional logging system designed for production environments with consistent property naming and professional messaging.
Core Logging Components
Structured Property Names
Consistent property naming across all components using PropertyNames class:
using WorkflowForge.Loggers;
// Core execution properties (consistent across all contexts)
PropertyNames.ExecutionId // Unique execution identifier
PropertyNames.ExecutionName // Human-readable execution name
PropertyNames.ExecutionType // Type of execution (Workflow, Operation, etc.)
// Workflow context properties
PropertyNames.FoundryExecutionId // Foundry instance identifier
PropertyNames.TotalOperationCount // Total operations in workflow
PropertyNames.ParentWorkflowExecutionId // For nested workflow tracking
// Error context properties
PropertyNames.ExceptionType // Exception type for structured error tracking
PropertyNames.ErrorCode // Error code for categorization
PropertyNames.ErrorCategory // Error category (ArgumentError, etc.)
// Compensation context properties
PropertyNames.CompensationOperationCount // Operations to compensate
PropertyNames.CompensationSuccessCount // Successful compensations
PropertyNames.CompensationFailureCount // Failed compensations
Corporate Message Templates
Professional static messages via WorkflowLogMessages class:
using WorkflowForge.Loggers;
// Workflow lifecycle messages
WorkflowLogMessages.WorkflowExecutionStarted
WorkflowLogMessages.WorkflowExecutionCompleted
WorkflowLogMessages.WorkflowExecutionFailed
WorkflowLogMessages.WorkflowExecutionCancelled
// Operation lifecycle messages
WorkflowLogMessages.OperationExecutionStarted
WorkflowLogMessages.OperationExecutionCompleted
WorkflowLogMessages.OperationExecutionFailed
// Compensation messages
WorkflowLogMessages.CompensationProcessStarted
WorkflowLogMessages.CompensationActionCompleted
WorkflowLogMessages.CompensationActionFailed
Logging Context Helpers
Standardized scope creation with LoggingContextHelper:
using WorkflowForge.Loggers;
// Create workflow execution scope with consistent properties
using var workflowScope = LoggingContextHelper.CreateWorkflowScope(logger, workflow, foundry);
// Create operation execution scope
using var operationScope = LoggingContextHelper.CreateOperationScope(logger, operation, stepIndex);
// Create compensation scope
using var compensationScope = LoggingContextHelper.CreateCompensationScope(logger, operationCount);
// Create error properties
var errorProps = LoggingContextHelper.CreateErrorProperties(exception, "WorkflowExecution");
logger.LogError(errorProps, exception, WorkflowLogMessages.WorkflowExecutionFailed);
Correlation ID Management
Correlation IDs are managed as foundry data, not logging properties, enabling tracking across sub-workflows:
using WorkflowForge.Loggers;
// Set correlation ID for tracking across operations and sub-workflows
LoggingContextHelper.SetCorrelationId(foundry, "REQ-12345");
// Get correlation ID from foundry
var correlationId = LoggingContextHelper.GetCorrelationId(foundry);
// Set parent workflow for nested workflow tracking
LoggingContextHelper.SetParentWorkflowExecutionId(childFoundry, parentWorkflow.Id.ToString());
// Create child foundry that inherits correlation context
var childFoundry = WorkflowForge.CreateFoundry("ChildWorkflow");
LoggingContextHelper.SetCorrelationId(childFoundry, correlationId); // Propagate correlation
LoggingContextHelper.SetParentWorkflowExecutionId(childFoundry, workflow.Id.ToString());
Scope-Based Property Inheritance
Properties automatically inherit through logging scopes:
// Workflow scope provides base context
using var workflowScope = LoggingContextHelper.CreateWorkflowScope(logger, workflow, foundry);
// All logs within this scope inherit workflow properties
logger.LogInformation(WorkflowLogMessages.WorkflowExecutionStarted);
for (int i = 0; i < workflow.Operations.Count; i++)
{
var operation = workflow.Operations[i];
// Operation scope inherits workflow context + adds operation context
using var operationScope = LoggingContextHelper.CreateOperationScope(logger, operation, i + 1);
// This log has both workflow AND operation context automatically
logger.LogDebug(WorkflowLogMessages.OperationExecutionStarted);
try
{
await operation.ForgeAsync(inputData, foundry, cancellationToken);
logger.LogDebug(WorkflowLogMessages.OperationExecutionCompleted);
}
catch (Exception ex)
{
// Error properties complement inherited scope properties
var errorProps = LoggingContextHelper.CreateErrorProperties(ex, "OperationExecution");
logger.LogError(errorProps, ex, WorkflowLogMessages.OperationExecutionFailed);
throw;
}
}
Built-in Logger Implementations
ConsoleLogger (Development)
Simple console output for development and testing:
var logger = new ConsoleLogger("MyWorkflow");
var foundry = WorkflowForge.CreateFoundry("TestWorkflow",
FoundryConfiguration.ForDevelopment().WithLogger(logger));
NullLogger (Testing)
No-op logger for unit testing:
var logger = NullLogger.Instance;
var foundry = WorkflowForge.CreateFoundry("TestWorkflow",
FoundryConfiguration.ForTesting().WithLogger(logger));
Extension-Based Advanced Logging
Core provides essential context - extensions handle specialized concerns:
Performance Metrics โ WorkflowForge.Extensions.Observability.Performance
- Duration tracking, memory usage, throughput metrics
- Uses
PerformancePropertyNames.DurationMs, etc.
Distributed Tracing โ WorkflowForge.Extensions.Observability.OpenTelemetry
- OpenTelemetry integration, span correlation, distributed context
Structured Logging โ WorkflowForge.Extensions.Logging.Serilog
- Rich structured logging, property enrichment, production sinks
// Core provides execution context, extensions add specialized capabilities
var foundryConfig = FoundryConfiguration.ForProduction()
.UseSerilog() // Rich structured logging
.EnablePerformanceMonitoring() // Performance metrics
.EnableOpenTelemetry(); // Distributed tracing
var foundry = WorkflowForge.CreateFoundry("ProductionWorkflow", foundryConfig);
Log Level Guidelines
- Trace: Middleware entry/exit (detailed flow control)
- Debug: Operation lifecycle (business process steps)
- Information: Workflow lifecycle (major business events)
- Warning: Compensation actions (recovery processes)
- Error: Execution failures (business/technical errors)
- Critical: System failures (infrastructure issues)
// Middleware uses Trace for detailed flow
logger.LogTrace(WorkflowLogMessages.MiddlewareExecutionStarted);
// Operations use Debug for business steps
logger.LogDebug(WorkflowLogMessages.OperationExecutionStarted);
// Workflows use Information for major events
logger.LogInformation(WorkflowLogMessages.WorkflowExecutionStarted);
// Compensation uses Warning (recovery scenario)
logger.LogWarning(WorkflowLogMessages.CompensationProcessStarted);
// Failures use Error with structured context
var errorProps = LoggingContextHelper.CreateErrorProperties(ex, "BusinessProcess");
logger.LogError(errorProps, ex, WorkflowLogMessages.OperationExecutionFailed);
This professional logging system provides:
- Consistent Property Naming: No conflicts with external systems (e.g., avoids Azure's OperationId)
- Corporate Messaging: Professional templates without informal language
- Correlation Tracking: End-to-end request tracking through foundry data
- Scope Inheritance: Automatic context propagation without property repetition
- Extension Separation: Core context vs specialized metrics in extensions
- Production Ready: Appropriate log levels for production log control
WorkflowForge Core - The foundation for reliable workflow orchestration
| 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.OpenTelemetry
OpenTelemetry integration for WorkflowForge providing distributed tracing, metrics collection, and observability instrumentation for comprehensive workflow monitoring and debugging. |
|
|
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.Performance
Performance monitoring and profiling extension for WorkflowForge providing detailed metrics, execution timing, memory usage tracking, and performance optimization insights for production workflows. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Initial release v1.0.0 of WorkflowForge core framework:
- Zero-dependency core workflow engine
- IWorkflowSmith and IWorkflowFoundry architecture
- Operations and builder patterns
- Built-in middleware support
- Comprehensive logging system
- SystemTime abstraction for testability