public void TestReverseTransition() { ServiceTicket serviceTicket = new ServiceTicket() { State = context.AllStates().First(e => e.Code == "Closed"), Name = "Closed service ticket" }; StateMachine.RequestTransition(serviceTicket, "Transition_ReOpen"); Assert.IsTrue(serviceTicket.State.Code == "Open"); }
/// <summary> /// When called with a valid entity and transition, it uses the transition handler for the given transition (as defined in the context) to /// perform the actual transition and change the state of the entity. /// </summary> /// <param name="entity"></param> /// <param name="transition"></param> /// <param name="argumentsMap">Any optional extra data that is needed for the transition. This data is passed to transition handler.</param> /// <returns></returns> public T RequestTransition(T entity, string transition, IDictionary <string, object> argumentsMap = null) { ITransitionHandler <T, M> handler; string currentState = entity.State == null ? "?" : entity.State.Code; // ? indicates null state string nextState; StateTransition thisTransition = Context.GetTransitions().FirstOrDefault(e => e.State == currentState && e.Transition == transition); if (thisTransition == null) { throw new Exception(String.Format("Invalid or unsupported transition - {0}", transition)); } nextState = thisTransition.NextState; if (!Context.AllStates().Any(e => e.Code == nextState)) { throw new Exception(String.Format("State: {0} is not defined.", nextState)); } if (!Context.GetTransitionHandlersMap().TryGetValue(transition, out handler)) { throw new Exception(String.Format("No handlers found for transition {0}.", transition.ToString())); } M nextStateObj = Context.AllStates().First(e => e.Code == nextState); //Get the M type object representing this state handler.ValidateTransition(entity, nextStateObj, argumentsMap); //Validate first handler.BeforeTransition(entity, argumentsMap); handler.Execute(entity, nextStateObj, argumentsMap); handler.AfterTransition(entity, argumentsMap); return(entity); }