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))); }
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)); }