Project Description
A simple state machine implementation written to replace WF in one of our projects. The interesting aspect of this library is that it comes with a DSL written in boo for quick and easy configuration and management of state machine definitions.
Technology: .NET 3.5 (VS2008), C#3.0, Boo Language, Rhino DSL
SimpleStateMachine is a library written in C# that provides an easy to use state machine that can easily be configured via a custom DSL (Domain Specific Language), inspired by an example in a book-in-progess on DSL's by Martin Fowler. SimpleStateMachine's
DSL is implemented using Boo and Rhino DSL by Ayende Rahien.
Martin Fowler's State Machine :
http://martinfowler.com/dslwip/Intro.html#TheStateMachineFramework
Building DSL's in Boo - a Manning EAP Book by Ayende Rahien:
http://www.manning.com/rahien/
The Boo Language home page:
http://boo.codehaus.org/
The motiviation for creating this library was a dissatisfaction with the complexity and weight of Windows Workflow Foundation for creating, maintaining, testing and versioning of what should have been simple state machine workflows in our applications. It is
suitable for use both in the user interface and in the middle tier and has optional facilities for directly interacting with your domain model if desired.
So far there is no documentation, but the project includes a unit test suite that demonstrates most functionality and two full blown windows forms samples that demonstrate and allow expirimentation with the features of the library.
SimpleStateMachine, as you would expect, allows for the definition of events, states, state transitions and user defined actions that can be executed before or after transitions. All features of the state machine itself can be configured via the DSL, and the
DSL can easily be enhanced to provide extended or custom functionality.
As for state persistence, you have to provide your own repository for persisting any domain objects you are using as the context for your state machine by implementing an IDomainContextRepository interface, but SimpleStateMachine will take care of invoking
the appropriate persistence actions after each state transition, including ensuring that the persistence operation takes place within a transaction if you have your state machine marked as transactional. Here you can find a
tutorial on how to use Castle's Active Record for persisting to a database.
This library can be useful in production projects as well or simply serve as an example of how to create a DSL using Boo and Rhino DSL and integrate it into an application.
See below for an example of the DSL syntax required to create a very simple state machine using SimpleStateMachine (the formatting is a bit off, but you get the idea)
#----------------------------------------
workflow "Telephone Call"
trigger @CallDialed
trigger @HungUp
trigger @CallConnected
trigger @LeftMessage
trigger @PlacedOnHold:
on_event @PlayMuzak
trigger @TakenOffHold
on_event @StopMuzak
trigger @PhoneHurledAgainstWall
state @OffHook:
when @CallDialed >> @Ringing
state @Ringing:
when @HungUp >> @OffHook
when @CallConnected >> @Connected
state @Connected:
when @LeftMessage >> @OffHook
when @HungUp >> @OffHook
when @PlacedOnHold >> @OnHold
state @OnHold:
when @TakenOffHold >> @Connected
when @HungUp >> @OffHook
when @PhoneHurledAgainstWall >> @PhoneDestroyed
state @PhoneDestroyed