internal TestUnitOfWork(IAggregateRootRepository aggregateRootRepository, IEventStore eventStore, IEventDispatcher eventDispatcher, IDomainEventSerializer domainEventSerializer, IDomainTypeNameMapper domainTypeNameMapper) { _eventStore = eventStore; _eventDispatcher = eventDispatcher; _domainEventSerializer = domainEventSerializer; _realUnitOfWork = new RealUnitOfWork(aggregateRootRepository, domainTypeNameMapper); }
/// <summary> /// Creates the view context with the given repository and type name mapper, storing the given event batch to be able to look up events in case it could make sense /// </summary> public DefaultViewContext(IAggregateRootRepository aggregateRootRepository, IDomainTypeNameMapper domainTypeNameMapper, IEnumerable <DomainEvent> eventBatch) { Items = new Dictionary <string, object>(); _aggregateRootRepository = aggregateRootRepository; _eventBatch = eventBatch.OrderBy(e => e.GetGlobalSequenceNumber()).ToList(); _realUnitOfWork = new RealUnitOfWork(_aggregateRootRepository, domainTypeNameMapper); }
public void MaybeApply(DomainEvent domainEvent, RealUnitOfWork realUnitOfWork, long requestedGlobalSequenceNumber) { // other roots' events are not relevant if (domainEvent.GetAggregateRootId() != _aggregateRootInfo.Id) { return; } var globalSequenceNumberFromEvent = domainEvent.GetGlobalSequenceNumber(); // don't do anything if we are not supposed to go this far if (globalSequenceNumberFromEvent > requestedGlobalSequenceNumber) { return; } // don't do anything if the event is in the past if (globalSequenceNumberFromEvent <= _globalSequenceNumber) { return; } // if this entry is a future version of the requested version, it's not ok.... sorry! if (_globalSequenceNumber > requestedGlobalSequenceNumber) { IsOk = false; return; } try { var sequenceNumberFromEvent = domainEvent.GetSequenceNumber(); var expectedNextSequenceNumber = _aggregateRootInfo.SequenceNumber + 1; if (expectedNextSequenceNumber != sequenceNumberFromEvent) { IsOk = false; return; } _aggregateRootInfo.Apply(domainEvent, realUnitOfWork); _globalSequenceNumber = globalSequenceNumberFromEvent; } catch (Exception exception) { _logger.Warn(exception, "Got an error while bringing cache entry for {0} up-to-date to {1}", _aggregateRootInfo.Id, requestedGlobalSequenceNumber); IsOk = false; } }
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); }
IEnumerable <DomainEvent> InnerProcessCommand(Command command) { var unitOfWork = new RealUnitOfWork(_aggregateRootRepository, _domainTypeNameMapper); var handler = _commandMapper.GetCommandAction(command); handler(new DefaultCommandContext(unitOfWork, command.Meta), command); var emittedEvents = unitOfWork.EmittedEvents.ToList(); if (!emittedEvents.Any()) { return(emittedEvents); } return(emittedEvents); }
public void CheckHydrationPerformance(int historyLength, bool useCaching) { var aggregateRootId = Guid.NewGuid(); GeneratePrettyLongHistory(aggregateRootId, historyLength); TakeTime("Load instance", () => { 100.Times(() => { var realUnitOfWork = new RealUnitOfWork(_cachingAggregateRootRepository, _domainTypeNameMapper); if (useCaching) { _cachingAggregateRootRepository.Get <Root>(aggregateRootId.ToString(), realUnitOfWork); } else { _realAggregateRootRepository.Get <Root>(aggregateRootId.ToString(), realUnitOfWork); } }); }); }
/// <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()); }
/// <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(); }
public FrozenAggregateRootService(AggregateRoot aggregateRootInfo, RealUnitOfWork realUnitOfWork) { _aggregateRootInfo = aggregateRootInfo; _realUnitOfWork = realUnitOfWork; }
public DefaultViewContext(IAggregateRootRepository aggregateRootRepository, IDomainTypeNameMapper domainTypeNameMapper) { _aggregateRootRepository = aggregateRootRepository; _realUnitOfWork = new RealUnitOfWork(_aggregateRootRepository, domainTypeNameMapper); }
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; }