Reputation: 715
I am working on my first asp.net mvc web application. I have a form that can be in 14 different states and depending of the current state, transition to other states are or are not possible. There is an average of 3-5 differents possible next state for each current state.
What I need to do now is trigger actions during some state transition. Depending on the initial state and the final states, some actions are trigged (emails are sent for example).
I started this by using switch statements:
switch ((int)currentState)
{
//Initial
case -1:
{
switch ((int)nextState)
{
//Next state: Inv. is waiting
case 1:
{
//Send email to x
emailHelper.Send(x,msg)
//Send email to Y
emailHelper.Send(y,anotherMsg)
}
case 2:
{
doSomethingelse()
}
break;
}
break;
}
//Inv is waiting
case 1:
{
switch ((int)nextState)
{
...
}
}
...
I think this solution would work fine for me, but I am wondering if I could use something better..Any suggestions?
Upvotes: 0
Views: 918
Reputation: 32576
If performance is not an issue at all, and the only thing you are interested is compact code, consider
switch(string.Format(CultureInfo.InvariantCulture, "{0} {1}", currentState, nextState))
{
case "-1 1":
//Send email to x
emailHelper.Send(x,msg);
//Send email to Y
emailHelper.Send(y,anotherMsg);
break;
case "-1 2":
doSomethingelse();
break;
....
}
You could also wait for C# 7.0 and use its new form of switch statement. Something like this:
struct State
{
int Current;
int Next;
}
....
State s;
switch (s)
{
case State x when (x.Current == -1 && x.Next == 1):
....
}
Upvotes: 2
Reputation: 6222
(pseudo code)
class StateHandler
{
int CurrentState;
int NextState;
Action MyAction;
public void Eval(int currentState, int nextState)
{
if(currentState == this.CurrentState && nextState == this.NextState)
{
this.MyAction();
}
}
}
Create a List and populate it with all known state transitions. Then just iterate the List and call Eval() on each item.
List<StateHandler> handlers = new List<StateHandler>();
handlers.Add(new StateHandler()
{
currentState = 0,
nextState = 1,
() => doSomeWork()
}
handlers.Add(new StateHandler()
{
currentState = 3,
nextState = 4,
() => doSomeOtherWork()
}
Upvotes: 1
Reputation: 19349
Perhaps you could use a data structure to store the states and transitions. For example, the state machine could be a Dictionary<int, State>
, where State
could be as simple as
struct State {
Dictionary<int, Action> transitions;
}
Performing a state transition then looks like
var action = states[currentState].transitions[nextState];
action();
currentState = nextState;
Of course, this solution could be more encapsulated, and could use checks as to whether a transition exists, but this is the gist of it
Upvotes: 2