/// <summary> /// Gets a valid transition based on the event. /// </summary> /// <param name="transitionEvent">The transition event.</param> /// <returns>The transition object.</returns> private StateTransition GetValidTransition(StateTransitionEvent transitionEvent) { var transitions = this.StateTransitions.Where(t => t.Start == this.CurrentState && t.AllowedEvents.HasFlag(transitionEvent)).ToList(); if (transitions == null || transitions.Count() != 1) { throw new NotSupportedException(string.Format("The requested (current state = {0}, event = {1}) operation is not supported.", this.CurrentState, transitionEvent)); } var transition = transitions[0]; return(transition); }
/// <summary> /// Moves to the next state asynchronously. /// </summary> /// <typeparam name="TResult">The type of the result object.</typeparam> /// <param name="entitySet">The target entity set.</param> /// <param name="action">The action name.</param> /// <param name="method">The method to be executed.</param> /// <param name="isRequestOffline">The flag indicating whether the current request is offline request.</param> /// <returns>The result object.</returns> private async Task <TResult> MoveNextAsync <TResult>(string entitySet, string action, Func <IContext, Task <TResult> > method, bool isRequestOffline) { StateTransitionEvent transitionEvent = await this.GetEventForRequestAsync(action, isRequestOffline); var transition = this.GetValidTransition(transitionEvent); switch (transition.Action) { case StateTransitionAction.ExecuteOnlineFirstIfFailedSwitchToOffline: return(await ExecuteOnlineIfFailedTriggerOfflineRequestAsync(entitySet, action, method, transition.Stop)); case StateTransitionAction.ExecuteOnlineAndOffline: return(await ExecuteBothOnlineAndOfflineAsync(method, transition.Stop)); case StateTransitionAction.ExecuteOnlineOnly: return(await ExecuteOnlineAsync(method, transition.Stop)); case StateTransitionAction.ExecuteOfflineOnly: return(await ExecuteOfflineAsync(method, transition.Stop)); case StateTransitionAction.SwitchToOffline: return(await SwitchToOfflineAndExecuteAsync(action, method, transition.Stop)); case StateTransitionAction.SwitchToOnline: return(await SwitchToOnlineAndExecuteIfFailedTriggerOfflineRequestAsync(entitySet, action, method, transition.Stop)); case StateTransitionAction.ChangeState: return(await Task.Run <TResult>(() => { SetState(transition.Stop); return null; })); default: throw new NotSupportedException("Unsupported transition action."); } }
/// <summary> /// Moves to the next state asynchronously. /// </summary> /// <param name="transitionEvent">The transition event.</param> /// <returns>No return.</returns> private async Task MoveNextAsync(StateTransitionEvent transitionEvent) { var transition = this.GetValidTransition(transitionEvent); switch (transition.Action) { case StateTransitionAction.SwitchToOffline: await this.SwitchToOfflineAsync(transition.Stop); break; case StateTransitionAction.SwitchToOnline: await this.SwitchToOnlineAsync(transition.Stop); break; case StateTransitionAction.ChangeState: this.SetState(transition.Stop); break; default: throw new NotSupportedException("Unsupported transition action."); } }
public StateTransition(ChainedContextState start, ChainedContextState stop, StateTransitionEvent allowedEvents, StateTransitionAction action) { this.Start = start; this.Stop = stop; this.AllowedEvents = allowedEvents; this.Action = action; }