private enum State { Open, Assigned, Deferred, Closed }
private enum Trigger { Assign, Defer, Close }
private readonly StateMachine<State, Trigger> _machine;
private readonly StateMachine<State, Trigger>.TriggerWithParameters<string> _assignTrigger;
private readonly string _title;
private string _assignee;
_machine = new StateMachine<State, Trigger>(State.Open);
_assignTrigger = _machine.SetTriggerParameters<string>(Trigger.Assign);
_machine.Configure(State.Open)
.Permit(Trigger.Assign, State.Assigned);
_machine.Configure(State.Assigned)
.OnEntryFrom(_assignTrigger, OnAssigned)
.PermitReentry(Trigger.Assign)
.Permit(Trigger.Close, State.Closed)
.Permit(Trigger.Defer, State.Deferred)
_machine.Configure(State.Deferred)
.OnEntry(() => _assignee = null)
.Permit(Trigger.Assign, State.Assigned);
_machine.Fire(Trigger.Close);
public void Assign(string assignee)
_machine.Fire(_assignTrigger, assignee);
public bool CanAssign => _machine.CanFire(Trigger.Assign);
_machine.Fire(Trigger.Defer);
private void OnAssigned(string assignee)
if (_assignee != null && assignee != _assignee)
SendEmailToAssignee("Don't forget to help the new employee!");
SendEmailToAssignee("You own it.");
private void OnDeassigned()
SendEmailToAssignee("You're off the hook.");
private void SendEmailToAssignee(string message)
Console.WriteLine("{0}, RE {1}: {2}", _assignee, _title, message);
public string ToDotGraph()
static void Main(string[] args)
var bug = new Bug("Incorrect stock count");