Today I finally got some time to research Stateless And you know, it’s awesome!
Key features:
- Generic support for states and triggers of any .NET type (numbers, strings, enums, etc.)
 - Hierarchical states
 - Entry/exit events for states
 - Guard clauses to support conditional transitions
 - Introspection
 - Ability to store state externally (for example, in a property tracked by Linq to SQL)
 - Parameterised triggers
 - Reentrant states
 
Let's consider the following example (it's available in the Stateless source code).
Program.cs
-        using System;
 -        using System.Collections.Generic;
 -        using System.Linq;
 -        using System.Text;
 -        
 -        namespace BugTrackerExample
 -        {
 -        class Program
 -        {
 -        static void Main(string[] args)
 -        {
 -        
 -        bug.Assign("Joe");
 -        bug.Defer();
 -        bug.Assign("Harry");
 -        bug.Assign("Fred");
 -        bug.Close();
 -        
 -        Console.ReadKey(false);
 -        }
 -        }
 -        }
 
Bug.cs
-        using System;</span>
 -        using System.Collections.Generic;
 -        using System.Linq;
 -        using System.Text;
 -        using Stateless;
 -        
 -        namespace BugTrackerExample
 -        {
 -        public class Bug
 -        {
 -        enum State { Open, Assigned, Deferred, Resolved, Closed }
 -        enum Trigger { Assign, Defer, Resolve, Close }
 -        
 -        State _state = State.Open;
 -        StateMachine<State, Trigger> _machine;
 -        StateMachine<State, Trigger>.TriggerWithParameters<string> _assignTrigger;
 -        
 -        string _title;
 -        string _assignee;
 -        
 -        public Bug(string title)
 -        {
 -        _title = title;
 -        
 -        
 -        _assignTrigger = _machine.SetTriggerParameters<string>(Trigger.Assign);
 -        
 -        _machine.Configure(State.Open)
 -        .Permit(Trigger.Assign, State.Assigned);
 -        
 -        _machine.Configure(State.Assigned)
 -        .SubstateOf(State.Open)
 -        .OnEntryFrom(_assignTrigger, assignee => OnAssigned(assignee))
 -        .PermitReentry(Trigger.Assign)
 -        .Permit(Trigger.Close, State.Closed)
 -        .Permit(Trigger.Defer, State.Deferred)
 -        .OnExit(() => OnDeassigned());
 -        
 -        _machine.Configure(State.Deferred)
 -        .OnEntry(() => _assignee = null)
 -        .Permit(Trigger.Assign, State.Assigned);
 -        }
 -        
 -        public void Close()
 -        {
 -        _machine.Fire(Trigger.Close);
 -        }
 -        
 -        public void Assign(string assignee)
 -        {
 -        _machine.Fire(_assignTrigger, assignee);
 -        }
 -        
 -        public bool CanAssign
 -        {
 -        get
 -        {
 -        return _machine.CanFire(Trigger.Assign);
 -        }
 -        }
 -        
 -        public void Defer()
 -        {
 -        _machine.Fire(Trigger.Defer);
 -        }
 -        
 -        void OnAssigned(string assignee)
 -        {
 -        if (_assignee != null && assignee != _assignee)
 -        SendEmailToAssignee("Don't forget to help the new guy.");
 -        
 -        _assignee = assignee;
 -        SendEmailToAssignee("You own it.");
 -        }
 -        
 -        void OnDeassigned()
 -        {
 -        SendEmailToAssignee("You're off the hook.");
 -        }
 -        
 -        void SendEmailToAssignee(string message)
 -        {
 -        Console.WriteLine("{0}, RE {1}: {2}", _assignee, _title, message);
 -        }
 -        }
 -        }
 
* Highlighted with QuickHighlighter.com