public static CommandProcessingException Create(Command command, Exception caughtException)
        {
            var message = string.Format("An error occurred while processing command {0} - any events emitted will most likely not have been saved", command);

            return new CommandProcessingException(message, caughtException)
            {
                FailedCommand = command
            };
        }
예제 #2
0
        public Action<ICommandContext, Command> GetCommandAction(Command command)
        {
            if (command is ExecutableCommand)
            {
                return (context, executableCommand) => ((ExecutableCommand)executableCommand).Execute(context);
            }

            throw new ArgumentException(string.Format(@"Could not find a command mapping for the command {0} - please derive your command off of ExecutableCommand or the generic Command<TAggregateRoot>, or supply an action mapping when configuring the command processor by going .Options(o => o.AddCommandMappings(...))", command));
        }
        public CommandProcessingResult ProcessCommand(Command command)
        {
            if (!command.Meta.ContainsKey(DomainEvent.MetadataKeys.CommandTypeName))
            {
                var commandTypeName = _domainTypeNameMapper.GetName(command.GetType());
                command.Meta[DomainEvent.MetadataKeys.CommandTypeName] = commandTypeName;
            }

            return _innerCommandProcessor.ProcessCommand(command);
        }
예제 #4
0
        public Action<ICommandContext, Command> GetCommandAction(Command command)
        {
            try
            {
                foreach (var mappings in _commandMappings)
                {
                    var handler = mappings.GetHandlerFor(command);

                    if (handler != null) return handler;
                }

                return _defaultCommandMapper.GetCommandAction(command);
            }
            catch (Exception exception)
            {
                throw new ArgumentException(string.Format("Could not find command action to execute for command {0} - please add suitable command mappings on the TestContext like this: context.AddCommandMappings(...)", command), exception);
            }
        }
예제 #5
0
        /// <summary>
        /// Processes the specified command by invoking the generic eventDispatcher method
        /// </summary>
        public CommandProcessingResult ProcessCommand(Command command)
        {
            _logger.Debug("Processing command: {0}", command);

            var emittedDomainEvents = new List<DomainEvent>();

            try
            {
                var batchId = Guid.NewGuid();

                _retryer.RetryOn<ConcurrencyException>(() =>
                {
                    var unitOfWork = new RealUnitOfWork(_aggregateRootRepository, _domainTypeNameMapper);
                    var handler = _commandMapper.GetCommandAction(command);

                    handler(new DefaultCommandContext(unitOfWork, command.Meta), command);

                    var eventsFromThisUnitOfWork = unitOfWork.EmittedEvents.ToList();

                    // if command processing yielded no events, there's no more work to do
                    if (!eventsFromThisUnitOfWork.Any()) return;

                    // first: save the events
                    _logger.Debug("Saving batch {0} with {1} events", batchId, eventsFromThisUnitOfWork.Count);

                    var eventData = eventsFromThisUnitOfWork.Select(e => _domainEventSerializer.Serialize(e)).ToList();

                    _eventStore.Save(batchId, eventData);

                    unitOfWork.RaiseCommitted(eventsFromThisUnitOfWork);

                    emittedDomainEvents.AddRange(eventsFromThisUnitOfWork);

                }, maxRetries: Options.MaxRetries);
            }
            catch (Exception exception)
            {
                // ordinary re-throw if exception is a domain exception
                if (Options.DomainExceptionTypes.Contains(exception.GetType()))
                {
                    throw;
                }

                throw CommandProcessingException.Create(command, exception);
            }

            try
            {
                _logger.Debug("Delivering {0} events to the dispatcher", emittedDomainEvents.Count);

                // when we come to this place, we deliver the events to the view manager
                _eventDispatcher.Dispatch(emittedDomainEvents);
            }
            catch (Exception exception)
            {
                var message =
                    string.Format(
                        "An error ocurred while dispatching events with global sequence numbers {0} to event dispatcher." +
                        " The events were properly saved in the event store, but you might need to re-initialize the" +
                        " event dispatcher",
                        string.Join(", ", emittedDomainEvents.Select(e => e.GetGlobalSequenceNumber())));

                throw new ApplicationException(message, exception);
            }

            return emittedDomainEvents.Any()
                ? CommandProcessingResult.WithNewPosition(emittedDomainEvents.Max(e => e.GetGlobalSequenceNumber()))
                : CommandProcessingResult.NoEvents();
        }
예제 #6
0
        IEnumerable<DomainEvent> InnerProcessCommand(RealUnitOfWork unitOfWork, Command command)
        {
            var handler = _commandMapper.GetCommandAction(command);

            handler(new DefaultCommandContext(unitOfWork, command.Meta), command);

            var emittedEvents = unitOfWork.EmittedEvents.ToList();

            if (!emittedEvents.Any()) return emittedEvents;

            return emittedEvents;
        }