示例#1
0
 public void AssertAddBlock(StackBlockSpecBase <TInput, TState, TOperationEvent> block)
 {
     if (ContainsFinallyBlock())
     {
         throw new OperationStackDeclarationException("No block can be added after a Finally block");
     }
 }
示例#2
0
        /// <summary>
        /// Gets then next block spec to execute
        /// </summary>
        /// <param name="currentBlock">The current block</param>
        /// <param name="target">The next target</param>
        /// <returns></returns>
        private StackBlockSpecBase <TInput, TState, TOperationEvent> GetNext(StackBlockSpecBase <TInput, TState, TOperationEvent> currentBlock, BlockResultTarget target)
        {
            switch (target.FlowTarget)
            {
            case BlockFlowTarget.Return:
                return(blocks.GetNext(currentBlock.Index));

            case BlockFlowTarget.Goto:
                return(blocks.GetByTagOrIndex(target.TargetTag, target.TargetIndex));

            case BlockFlowTarget.Retry:
                return(currentBlock);

            case BlockFlowTarget.Reset:
                return(blocks.GetFirst());

            case BlockFlowTarget.Restart:
                return(blocks.GetFirst());

            case BlockFlowTarget.Skip:
                return(blocks.SkipBy(currentBlock.Index, target.TargetIndex));

            case BlockFlowTarget.Complete:
            case BlockFlowTarget.Fail:
                return(blocks.GotoEnd(currentBlock.Index));

            default:
                return(null);
            }
        }
示例#3
0
 public OperationStackExecutionState(OperationStackOptions options, StackBlocks <TInput, TState, TOperationEvent> blocks, TInput stackInput, TState initialState)
 {
     this.options      = options;
     this.blocks       = blocks;
     StackInput        = stackInput;
     CurrentBlockSpec  = blocks.GetFirst();
     this.InitialState = initialState;
     State             = initialState;
 }
示例#4
0
        /// <summary>
        /// Handle current block result and set next block to execute
        /// </summary>
        /// <param name="block">The execution block</param>
        /// <param name="blockResult">The execution block result</param>
        public void HandleBlockResultAndSetNext(StackBlockBase <TInput, TState, TOperationEvent> block, IBlockResult blockResult)
        {
            PreviousBlockSpec = CurrentBlockSpec;

            //Add to stack trace
            //Should we add trace to empty event blocks? To event blocks?
            StackTrace.Add(new BlockTraceResult <TOperationEvent>(block, blockResult));

            //Handle Reset state in case of reset
            State = blockResult.Target.FlowTarget == BlockFlowTarget.Reset ?
                    (blockResult.Target.ResetStateSet ? (TState)Convert.ChangeType(blockResult.Target.State, typeof(TState)) : default(TState)) :
                    block.StackState;

            //Check fail state
            if (options.FailOnException && block.Events.HasUnhandledErrors)
            {
                IsFail = true;
            }

            //Override result is only applicable on Complete. Cache here in case of finally
            OverrideResult = blockResult.Target.OverrideResult;

            //Set next input
            NextInput = blockResult.GetNextInput();

            //Get next block to execute
            CurrentBlockSpec = IsFail ? blocks.GotoEnd(CurrentBlockSpec.Index) : GetNext(CurrentBlockSpec, blockResult.Target);

            //If complete set overriden result if any
            if (CurrentBlockSpec == null && OverrideResult.HasValue)
            {
                //Set last result
                LastResult = OverrideResult;
                blockResult.OverrideResult(OverrideResult);
            }
            else
            {
                //Set last result
                LastResult = blockResult.Result;
            }
        }
示例#5
0
 public OperationStack <TInput, TState, TOperationEvent, TResult> CreateNew <TResult>(StackBlockSpecBase <TInput, TState, TOperationEvent> block)
 {
     Blocks.AssertAddBlock(block);
     return(new OperationStack <TInput, TState, TOperationEvent, TResult>(Blocks.Concat(block), Options, InitialStateBuilder, HasInput));
 }
示例#6
0
 public IEnumerable <StackBlockSpecBase <TInput, TState, TOperationEvent> > Concat(StackBlockSpecBase <TInput, TState, TOperationEvent> block)
 => blocks.Concat(new[] { block });
示例#7
0
 public void Add(StackBlockSpecBase <TInput, TState, TOperationEvent> block) => blocks.Add(block);