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