public async Task <StateMachineProcessingResults> OnEventAsync(Type stateType, object state, ICorrelationEvent evt)
        {
            if (_stateMachineTypes == null)
            {
                throw new Exception("Saga configuration error. You need to configure the SagaStateMachineFactoryBuilder.");
            }

            var stateMachineType = _stateMachineTypes[stateType];

            if (stateMachineType == null)
            {
                if (_stateMachineTypes.Values.Count == 0)
                {
                    throw new Exception($"State machine type {stateType} not found. No state machines have been scanned. Did you add the assembly via SagaStateMachineFactoryBuilder.WithStateMachinesInAssembiles?");
                }
                throw new Exception($"State machine type {stateType} not found out of {_stateMachineTypes.Values.Count} state machines.");
            }

            if (_container == null)
            {
                throw new Exception("IContainer supplied to SagaStateMachineFactoryBuilder is null.");
            }

            var stateMachine = _container.GetInstance(stateMachineType);
            var methodInfo   = stateMachineType.GetMethod("ProcessNextStep", new[] { typeof(Guid), typeof(ICorrelationEvent), stateType, typeof(StateMachineProcessingResults) });

            if (methodInfo == null || stateMachine == null)
            {
                throw new Exception($"No valid state machine {stateMachineType.Name} for state {stateType.Name}.");
            }
            {
                var result = new StateMachineProcessingResults();
                await((Task)methodInfo?.Invoke(stateMachine, new[] { evt.CorrelationId, evt, state, result })).ConfigureAwait(false);
                return(result);
            }
        }
        public async Task Initialize(T state)
        {
            var correlationId = Guid.NewGuid();
            await _repository.Create(correlationId, state).ConfigureAwait(false);

            // create an event to represent the new state of the state machine, having an object instead of null
            // avoids having to perform a null check in each state machine
            var stateMachineCreatedEvent = new StateMachineCreatedEvent {
                CorrelationId = correlationId
            };
            var firstStepResult = new StateMachineProcessingResults();

            await ProcessNextStep(correlationId, stateMachineCreatedEvent, state, firstStepResult).ConfigureAwait(false);

            if (firstStepResult.IsSagaComplete)
            {
                // even though crazy, handle if a saga of a single command has been created
                await _repository.Delete(correlationId).ConfigureAwait(false);
            }
            else
            {
                await _repository.Update(correlationId, state).ConfigureAwait(false);
            }
        }
 public abstract Task ProcessNextStep(Guid correlationId, ICorrelationEvent evt, T state, StateMachineProcessingResults results);