In the previous post we saw how we can implement the state pattern (I know, I didnt show you the purist way of using the State pattern ) and include in the state execution the flow logic.
This technique is fine but it requires a lot of effort in the implementation and requires a lot of maintenance, plus it has the GAP of forcing us to re-run the CanExecute delegate every time we want to execute a specific action.
On the web I have found some solutions that personally didnt satisfy me at all. I personally believe that the best way of designing a state machine workflow is to use a workflow engine and NET Framework provides with NET 4 an amazing state engine. Anyway lets see what the web offers instead of using WF 4.
Stateless Open source project
Stateless is an Open source project hosted on Google code and available here: http://code.google.com/p/stateless/; it is a C# implementation of a stateless workflow using the BOO language.
We have the same domain exposed in the previous post but in this case we modified a little bit the Order object and we do not use anymore the Command pattern.
The class Order has 5 different methods that can modify its state in the following way:
They do not verify anymore if the action can or cannot be execute, we just know that the Create method, for example, modifies the state of the Order to Created.
Now it is time to wrap this code in a separated class that we will call OrderService and that is identified in DDD as a Domain Service object, a service used in the domain space to wrap business logic and keep it outside the Entity object. The final result should like this one:
The trick with http://code.google.com/p/stateless/ is to split the service in two parts, the first one is used to Bootstrap the stateless framework in the following way:
And then we add a method in the service that will be used to Fire a specific state change, like this one:
Now, by default, Stateless raises an error (Exception) if the operation cant be executed. The following test demonstrates the exception raised by stateless:
The exception is of type InvalidOperationException.