public async Task Send(SagaConsumeContext <TInstance, TData> context, IPipe <SagaConsumeContext <TInstance, TData> > next)
        {
            var eventContext = new StateMachineEventContext <TInstance, TData>(_machine, context.Saga, _event, context.Message, context.CancellationToken);

            eventContext.GetOrAddPayload(() => context);
            eventContext.GetOrAddPayload(() => (ConsumeContext <TData>)context);
            eventContext.GetOrAddPayload(() => (ConsumeContext)context);

            State <TInstance> currentState = await _machine.Accessor.Get(eventContext).ConfigureAwait(false);

            IEnumerable <Event> nextEvents = _machine.NextEvents(currentState);

            if (nextEvents.Contains(_event))
            {
                await _machine.RaiseEvent(eventContext).ConfigureAwait(false);

                if (_machine.IsCompleted(context.Saga))
                {
                    await context.SetCompleted().ConfigureAwait(false);
                }
            }
            else
            {
                throw new NotAcceptedStateMachineException(typeof(TInstance), typeof(TData), context.CorrelationId ?? Guid.Empty, currentState.Name);
            }
        }
        /// <summary>
        ///     Transition a state machine instance to a specific state, producing any events related
        ///     to the transaction such as leaving the previous state and entering the target state
        /// </summary>
        /// <typeparam name="TInstance">The state instance type</typeparam>
        /// <param name="machine">The state machine</param>
        /// <param name="instance">The state instance</param>
        /// <param name="state">The target state</param>
        /// <param name="cancellationToken"></param>
        public static Task TransitionToState <TInstance>(this StateMachine <TInstance> machine, TInstance instance, State state,
                                                         CancellationToken cancellationToken = default)
            where TInstance : class
        {
            var accessor = machine.Accessor;
            var toState  = machine.GetState(state.Name);

            Activity <TInstance> activity = new TransitionActivity <TInstance>(toState, accessor);
            Behavior <TInstance> behavior = new LastBehavior <TInstance>(activity);

            var eventContext = new StateMachineEventContext <TInstance>(machine, instance, toState.Enter, cancellationToken);

            BehaviorContext <TInstance> behaviorContext = new EventBehaviorContext <TInstance>(eventContext);

            return(behavior.Execute(behaviorContext));
        }
        public static async Task <IEnumerable <Event> > NextEvents <T, TInstance>(this T machine, TInstance instance)
            where T : class, StateMachine, StateMachine <TInstance>
            where TInstance : class
        {
            if (machine == null)
            {
                throw new ArgumentNullException(nameof(machine));
            }
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }

            var context = new StateMachineEventContext <TInstance>(machine, instance, machine.Initial.Enter, default(CancellationToken));

            return(machine.NextEvents(await machine.Accessor.Get(context).ConfigureAwait(false)));
        }
Пример #4
0
        public async Task Send(SagaConsumeContext <TInstance, TData> context, IPipe <SagaConsumeContext <TInstance, TData> > next)
        {
            var eventContext = new StateMachineEventContext <TInstance, TData>(context, _machine, context.Saga, _event, context.Message);

            eventContext.GetOrAddPayload(() => context);
            eventContext.GetOrAddPayload(() => (ConsumeContext <TData>)context);
            eventContext.GetOrAddPayload(() => (ConsumeContext)context);

            State <TInstance> currentState = await _machine.Accessor.Get(eventContext).ConfigureAwait(false);

            try
            {
                await _machine.RaiseEvent(eventContext).ConfigureAwait(false);

                if (_machine.IsCompleted(context.Saga))
                {
                    await context.SetCompleted().ConfigureAwait(false);
                }
            }
            catch (UnhandledEventException ex)
            {
                throw new NotAcceptedStateMachineException(typeof(TInstance), typeof(TData), context.CorrelationId ?? Guid.Empty, currentState.Name, ex);
            }
        }
        Task EventLift <TInstance> .Raise(TInstance instance, CancellationToken cancellationToken)
        {
            var context = new StateMachineEventContext <TInstance>(_machine, instance, _event, cancellationToken);

            return(_machine.RaiseEvent(context));
        }