2. Concepts - iwannabebot/SharpFsm GitHub Wiki

Understanding the core building blocks of SharpFsm will help you design cleaner, maintainable, and more expressive state machines.

📌 State

A state represents a distinct condition or situation in the lifecycle of an object or process.

How to Define States

States are typically defined using an enum for strong typing:

public enum TicketState
{
    New,
    InProgress,
    Resolved,
    Closed
}

Best Practices

  • Use clear and descriptive names (e.g., PendingReview > Pending).
  • Keep the enum definition in a shared or domain-specific namespace.
  • Avoid ambiguous or overloaded terms.

🔁 Transition

A transition defines how the FSM moves from one state to another. Each transition can specify:

  • Source state: where the transition starts
  • Target state: where it ends
  • Condition (optional): a predicate to allow or deny the transition
  • Side effect (optional): an action to run during the transition

Example

.AddTransition(TicketState.New, TicketState.InProgress)
    .When(ctx => ctx.IsAgentAssigned)
    .WithSideEffect((ctx, _, _) => Console.WriteLine("Notified agent"))
    .Done()

Condition

A condition (or guard) is a predicate function used to determine if a transition should proceed.

ctx => ctx.IsAgentAssigned

Return true to allow the transition, false to block it.

Side Effect

A side effect is a piece of logic executed during a transition. Use it for logging, notifications, or state synchronization.

(ctx, _, _) => Console.WriteLine("Customer notified")

📦 Context

The context is an object passed into transitions that contains runtime data.

Example

public class TicketContext
{
    public bool IsAgentAssigned { get; set; }
    public string CustomerEmail { get; set; }
}

Usage

AddTransition(TicketState.New, TicketState.InProgress)
    .When(ctx => ctx.IsAgentAssigned)
    .WithSideEffect((ctx, _, _) => Notify(ctx.CustomerEmail))

🧬 State Machine Definition

A state machine definition encapsulates:

  • All valid states
  • All transitions between those states
  • The initial state
  • Any associated logic (guards, side effects, outputs)

This definition is used to construct a state machine instance via a builder.

var context = new TicketContext { IsAgentAssigned = false, CustomerEmail = "[email protected]" };
var definition = FiniteStateMachineBuilder<TicketState, TicketContext>.Create("Ticket")
    .WithInitialState(TicketState.New)
    .AddTransition(TicketState.New, TicketState.InProgress)
        .When(ctx => ctx.IsAgentAssigned)
        .WithSideEffect((ctx, _, _) => Notify(ctx.CustomerEmail))
        .Done()
    .Build();
var fsm = new FiniteStateMachine<TicketState, TicketContext>(definition);
fsm.TryTransitionTo(TicketState.InProgress, context); // Does not move to InProgress
context.IsAgentAssigned = true;
fsm.TryTransitionTo(TicketState.InProgress, context); // Moves to InProgress