State machine engine for business process automation in the Birko Framework. Provides trigger-based transitions, fluent builder API, guards, actions, and diagram visualization.
- Fluent Builder API — Define workflows with a readable, chainable syntax
- Trigger-based Transitions — Fire named triggers (
"approve","cancel") rather than direct state changes - Generic
WorkflowDefinition<TData>— Type-safe guards and actions on your workflow data - Guards — Conditional transitions with denial reasons
- Actions — Async entry/exit/transition actions with cancellation support
- State History — Full transition audit trail via
StateChangeRecord - Visualization — Generate Mermaid and Graphviz DOT diagrams from definitions
- DI Integration —
AddWorkflowEngine()for Microsoft.Extensions.DependencyInjection - Persistence —
IWorkflowInstanceStore<TData>with SQL, ElasticSearch, MongoDB, RavenDB, and JSON providers - Fault handling — Automatic faulted state on action failures
var workflow = new WorkflowBuilder<OrderData>("OrderProcessing")
.InitialState("Pending")
.State("Pending").Description("Awaiting payment").And()
.State("Paid").OnEntry(async (inst, ct) => { /* send confirmation */ }).And()
.State("Shipped").And()
.State("Delivered").IsFinal().And()
.State("Cancelled").IsFinal().And()
.Transition("pay", "Pending", "Paid")
.Guard(inst => inst.Data.PaymentReceived, "Payment required")
.And()
.Transition("ship", "Paid", "Shipped").And()
.Transition("deliver", "Shipped", "Delivered").And()
.Transition("cancel", "Pending", "Cancelled").And()
.Transition("cancel", "Paid", "Cancelled").And()
.Build();var engine = new WorkflowEngine();
var instance = WorkflowInstance<OrderData>.Create(workflow, orderData);
var result = await engine.FireAsync(workflow, instance, "pay");
if (result.IsSuccess)
Console.WriteLine($"Moved from {result.FromState} to {result.ToState}");
else if (result.IsDenied)
Console.WriteLine($"Denied: {string.Join(", ", result.DenialReasons)}");
else if (result.IsNotFound)
Console.WriteLine($"No transition for trigger '{result.Trigger}' in state '{result.FromState}'");var triggers = engine.GetPermittedTriggers(workflow, instance);
// ["pay", "cancel"] when in "Pending" statevar mermaid = new MermaidDiagramGenerator();
Console.WriteLine(mermaid.Generate(workflow));
// stateDiagram-v2
// [*] --> Pending
// Pending : Awaiting payment
// Pending --> Paid : pay
// ...
var dot = new DotDiagramGenerator();
Console.WriteLine(dot.Generate(workflow));
// digraph "OrderProcessing" { ... }services.AddWorkflowEngine();
// With state change publishing
services.AddWorkflowEngine(options =>
{
options.PublishStateChanges = true;
});var restored = WorkflowInstance<OrderData>.Restore(
instanceId: savedId,
currentState: "Paid",
status: WorkflowStatus.Active,
data: loadedData,
history: savedHistory);- Find matching transition (currentState + trigger)
- Evaluate guards — collect denial reasons
- Execute OnExit actions → transition actions → set state → OnEntry actions
- Mark as Completed if final state reached
- Record history and invoke state change callback
- On action failure: set Faulted status, throw
WorkflowActionException
| Type | Purpose |
|---|---|
WorkflowBuilder<TData> |
Fluent API to define workflows |
WorkflowDefinition<TData> |
Immutable workflow blueprint |
WorkflowInstance<TData> |
Mutable state holder |
WorkflowEngine |
Stateless transition executor |
TransitionResult |
Success/Denied/NotFound outcome |
MermaidDiagramGenerator |
Mermaid stateDiagram-v2 output |
DotDiagramGenerator |
Graphviz DOT output |
MIT License - see License.md