Carubbi.StateMachine 2.0.2

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

Carubbi.StateMachine

A state machine library for .NET 10 with compile-time source generation, fluent startup configuration and dependency injection integration. No attributes, no runtime weaving, no reflection.

How it works

  1. Declare your entity as a partial class and write its transition logic in <Method>Core partial method pairs.
  2. Register the machine at startup via services.AddStateMachine<TEntity>(...), binding transitions to methods with a fluent API.
  3. The bundled Roslyn source generator emits the public wrapper methods and the StateMachine property for every registered entity.
public partial class Order
{
    // Public API is generated for you: Ship(), Deliver(), Cancel()
    private partial void ShipCore()
    {
        // transition logic
    }

    private partial void DeliverCore() { }

    private partial void CancelCore() { }
}
var services = new ServiceCollection();

services.AddStateMachine<Order>(fsm => fsm
    .Initial("Draft")
    .Allow("Draft", "Placed").For(nameof(Order.Ship))
    .Allow("Placed", "Shipped").For(e => e.Deliver())
    .Allow("Draft", "Canceled").For(nameof(Order.Cancel)));

Usage:

var order = new Order();
order.Ship();                              // guarded by the configured transitions
Console.WriteLine(order.StateMachine.CurrentState);   // "Placed"

order.StateMachine.TransitionStarted += (_, e) => e.Cancel = /* ... */;

Rules

  • Transition logic lives in XxxCore partial method pairs (empty defining declaration + implementing declaration). The generator publishes the public Xxx wrapper.
  • Methods are only valid while the entity's current state matches one of the Allow(from, to) bindings registered for that method.
  • When no binding matches:
    • StateMachine.IgnoreInvalidOperations == false (default): an InvalidOperationException describing the current and allowed states is thrown.
    • IgnoreInvalidOperations == true: the body is skipped silently (non-void wrappers return default).
  • Handlers of TransitionStarted may set Cancel = true; the transition and method body are then skipped.
  • TransitionEnded fires after the state changed.
  • Accessing an entity whose type was never configured throws a descriptive InvalidOperationException.

Diagnostics

ID Severity Meaning
SM001 Error Registered entity is not declared partial.
SM003 Error Generated wrapper/property name collides with an existing member.
SM004 Error Core method declares out/ref parameters (cannot forward on skipped transitions).
SM005 Error Generic transition methods are not supported.

Ambiguous configurations (two transitions from the same state bound to one method, missing initial state) are rejected eagerly at configuration time.

Breaking changes from v1.x

  • Targets .NET 10 only.
  • [InitialState] / [Transition] attributes, IStatedEntity and StateMachine.Configure() are gone; configuration moved to the fluent builder at startup.
  • Entities are plain partial classes; the StateMachine property is generated (get-only, lazy) instead of user-declared.
  • Replaced NConcern/CNeptune AOP with a Roslyn incremental source generator (Carubbi.StateMachine.Generators) - fully AOT-safe.
  • Tests migrated from MSTest v1 to TUnit.

Packages

  • Carubbi.StateMachine - core library + DI integration (Microsoft.Extensions.DependencyInjection.Abstractions).
  • Carubbi.StateMachine.Generators - shipped automatically as an analyzer dependency of the main package.

Build & test

Requires the .NET 10 SDK.

dotnet build
dotnet test
Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
2.0.2 87 8/24/2026
2.0.1 89 8/24/2026
2.0.0 97 8/24/2026
1.1.0 1,233 11/4/2018
1.0.0 1,035 8/29/2018