Example #1
0
        /// <summary>
        ///   NOTE 1: http://cs.hubfs.net/blogs/hell_is_other_languages/archive/2008/01/16/4565.aspx
        /// </summary>
        public void TriggerTransition(TState targetState,
                                      dynamic args = default(dynamic))
        {
            Ensure.That <ArgumentException>(targetState != null, "targetState not supplied.");

            try
            {
                if (CurrentState == targetState && !PermitSelfTransition)
                {
                    throw new Exception(); //refactor to refine exception
                }

                if (CurrentState == FinalState)
                {
                    throw new Exception(); //refactor to refine exception
                }

                if ((CurrentState != targetState || (CurrentState == targetState && !BypassTransitionBehaviorForSelfTransition)))
                {
                    var matches = StateTransitions.Where(t =>
                                                         t.InitialStates.Where(s => s == CurrentState).Any() &&
                                                         t.EndStates.Where(e => e == targetState).Any());
                    if (matches.Any())
                    {
                        using (var t = new TransactionScope())
                        //this could be in-memory transactionalised using the memento pattern, or information could be sent to F# (see NOTE 1)
                        {
                            OnRaiseBeforeEveryTransition();
                            CurrentState.ExitAction(args);
                            matches.First().TransitionAction(targetState, this, args);
                            targetState.EntryAction(args);
                            CurrentState = targetState;
                            OnRaiseAfterEveryTransition();
                            t.Complete();
                        }
                    }
                    else
                    {
                        if (Parent == null)
                        {
                            throw new Exception(); //to be caught below, refactor
                        }

                        Parent.TriggerTransition(targetState, args);
                    }
                }
            }
            catch (Exception e)
            {
                throw new InvalidStateTransitionException <TState>(CurrentState, targetState, innerException: e);
            }
        }