Lombda.StateMachine 1.0.1

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

Lombda.StateMachine

A powerful and flexible state machine library for .NET 8.0 that supports concurrent execution, complex state transitions, and type-safe operations. This library provides both generic and non-generic state machine implementations with extensive event handling and logging capabilities.

Features

  • Generic and Non-Generic State Machines: Support for both strongly-typed and object-based state machines
  • Concurrent Execution: Built-in thread management with configurable thread limits
  • Flexible State Transitions: Conditional state transitions with support for data transformation
  • Event-Driven Architecture: Comprehensive event system for monitoring state machine execution
  • Lambda State Support: Easy integration of lambda functions as states
  • Cancellation Support: Graceful cancellation and cleanup mechanisms
  • Runtime Properties: Persistent storage for state machine runtime data
  • Step Recording: Optional execution step recording for debugging and analysis
  • Async/Await Support: Full asynchronous operation support throughout the library

Installation

Add the project reference to your solution or include the source files directly in your project.

Quick Start

Creating State Machines

States essentially transforms the Input into the Output

Where FooState : BaseState<InputType, OutputType>

Invoke(InputType input) Must Return the Output Type (Strongly Typed)

You can only Transition to a state where the Output of the current state is the Input to the next state

class ConvertStringToIntState : BaseState<string, int>
{
    public override async Task<int> Invoke(string input)
    {
        return int.Parse(this.Input)
    }
}

You can build pipelines of states and let the agent transition between them based on the results.

Creating State Machines With Input & Output Types

//Where string is Input and int is Output
StateMachine<string, int> stateMachine = new();

//Set start state with string Input
stateMachine.SetEntryState(inputState);

//Set state where output is
stateMachine.SetOutputState(resultState);

//Return list of Output objects from State 
//List because machine might generate more than 1 output depending on flow
List<int> stateResults = await stateMachine.Run("3");---

Allow states to transition to other states in a parallel workflow

//AllowsParallelTransitions = true Allows state Outputs to transition to all states that meet the criteria
ConvertStringToIntState inputState = new() { AllowsParallelTransitions = true };

IntPlus3State state3 = new();
IntPlus4State state4 = new();

//CombineInput = true only does 1 execution reguardless of # of Inputs
//Handle all of the Inputs
SummingState summingState = new() { CombineInput = true };
ConvertIntToStringState resultState = new();

//should happen in parallel and get result
inputState.AddTransition(state3);
inputState.AddTransition(state4);

//summing State will get both results next tick
state3.AddTransition(summingState);
state4.AddTransition(summingState);

//Will sum all inputs 
summingState.AddTransition(resultState);

//Convert result and End the State Machine 
resultState.AddTransition(new ExitState());

//Create Input & Output State Machine
StateMachine<string, string> stateMachine = new();

//Define Entry and Output States
stateMachine.SetEntryState(inputState);
stateMachine.SetOutputState(resultState);

//Run the StateMachine
List<string?> stateResults = await stateMachine.Run("3");

Simple Conversion from different Input to Output types

ConvertStringToIntState inputState = new();
ConvertStringToIntState resultState = new();

//Input State will convert string to int
inputState.AddTransition((result) => result.ToString(), resultState);

resultState.AddTransition(new ExitState());

StateMachine<string, int?> stateMachine = new();

stateMachine.SetEntryState(inputState);
stateMachine.SetOutputState(resultState);

var stateResults = await stateMachine.Run(["3","2","4"]);

Console.WriteLine($"State Results: {string.Join(", ", stateResults.Select(r => string.Join(", ", r)))}");

Assert.IsTrue(stateResults[0].Contains(3));

API Reference

StateMachine Class

public class StateMachine
{
    // Properties
    public int MaxThreads { get; set; }
    public bool RecordSteps { get; set; }
    public bool IsFinished { get; set; }
    public ConcurrentDictionary<string, object> RuntimeProperties { get; set; }
    public List<StateProcess> ActiveProcesses { get; }
    public CancellationToken CancelToken { get; }

    // Events
    public event Action OnBegin;
    public event Action OnTick;
    public event Action<StateProcess>? OnStateEntered;
    public event Action<BaseState>? OnStateExited;
    public event Action<StateProcess>? OnStateInvoked;
    public event Action? FinishedTriggered;
    public event Action? CancellationTriggered;
    public event Action<string>? VerboseLog;

    // Methods
    public async Task Run(BaseState runStartState, object? input = null);
    public void Stop();
    public void Finish();
    public void ResetRun();
}

StateMachine<TInput, TOutput> Class

public class StateMachine<TInput, TOutput> : StateMachine
{
    // Properties
    public List<TOutput>? Results { get; }
    public BaseState StartState { get; set; }
    public BaseState ResultState { get; set; }

    // Methods
    public async Task<List<TOutput?>> Run(TInput input);
    public async Task<List<List<TOutput?>>> Run(TInput[] inputs);
    public void SetEntryState(BaseState startState);
    public void SetOutputState(BaseState resultState);
}

Contributing

When contributing to this project:

  1. Follow the existing code style and patterns
  2. Add comprehensive unit tests for new functionality
  3. Update documentation for public API changes
  4. Ensure all tests pass before submitting

License

This project is available under the terms specified in the project license.

Changelog

Version 1.0.0

  • Initial release with core state machine functionality
  • Generic and non-generic implementations
  • Comprehensive event system
  • Thread management and cancellation support
  • Full test coverage
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

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
1.0.1 37 8/2/2025

Fix to restore the _Invoke function