public void HandleEvent(Any @event, IEventContext context) { Unwrap(() => { var obj = AnySupport.Decode(@event); if (!CurrentBehaviors .Any(behavior => GetCachedBehaviorReflection(behavior) .GetEventHandler(obj.GetType()) .Match(handler => { var active = true; var ctx = new EventBehaviorContext(context, behaviors => { // ReSharper disable once AccessToModifiedClosure if (!active) { throw new InvalidOperationException("Context is not active!"); } CurrentBehaviors = ValidateBehaviors(behaviors).ToArray(); }); handler.Invoke(behavior, obj, ctx); active = false; return(true); }, () => false) ) ) { throw new CloudStateException( $"No event handler [{obj.GetType()}] found for any of the current behaviors: {BehaviorsString}"); } }); }
async Task <State <TInstance> > StateAccessor <TInstance> .Get(InstanceContext <TInstance> context) { var state = await _stateAccessor.Get(context).ConfigureAwait(false); if (state == null) { var behaviorContext = new EventBehaviorContext <TInstance>(context); await _initialBehavior.Execute(behaviorContext).ConfigureAwait(false); state = await _stateAccessor.Get(context).ConfigureAwait(false); } return(state); }
/// <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)); }