public RestoreAggregateCommandResult <TAggregate> Execute(RestoreEventSourcedAggregateCommand <TIdentity, TSnapshot> command) { var snapshotEnvelope = _snapshotDataContext.Ask <TSnapshot, TIdentity>(command.Identity); IReadOnlyCollection <EventEnvelope> eventEnvelopes; TAggregate aggregate; var previouslyDispatchedMessages = new List <Guid>(); int currentVersion; if (snapshotEnvelope != null) { eventEnvelopes = _eventStoreContext.AskEventsFor(command.Identity, snapshotEnvelope.Snapshot.Version); previouslyDispatchedMessages.AddRange(snapshotEnvelope.Metadata.DispatchedMessageIds); currentVersion = snapshotEnvelope.Snapshot.Version + eventEnvelopes.Count; aggregate = (TAggregate)Activator.CreateInstance(typeof(TAggregate), command.Identity, snapshotEnvelope.Snapshot, eventEnvelopes); } else { eventEnvelopes = _eventStoreContext.AskEventsFor(command.Identity); var events = eventEnvelopes.Select(x => x.Event).ToList(); currentVersion = eventEnvelopes.Count; aggregate = (TAggregate)Activator.CreateInstance(typeof(TAggregate), command.Identity, events); } _dispatchedMessages.AddRange(eventEnvelopes.Select(x => x.Metadata.DispatchedMessageId)); previouslyDispatchedMessages = previouslyDispatchedMessages.Union(_dispatchedMessages, new GuidComparer()).ToList(); if (previouslyDispatchedMessages.Contains(command.IncomingMessageId)) { var needPublishedEvents = eventEnvelopes .Where(x => x.Metadata.DispatchedMessageId == command.IncomingMessageId) .Select(x => x.Event) .ToList(); return(new RestoreAggregateCommandResult <TAggregate>(aggregate, _dispatchedMessages, true, needPublishedEvents)); } var expectedVersion = command.Version; if (currentVersion > expectedVersion || aggregate.Version != expectedVersion) { throw new InvalidOperationException(); } _dispatchedMessages.Add(command.IncomingMessageId); return(new RestoreAggregateCommandResult <TAggregate>(aggregate, _dispatchedMessages, false, Enumerable.Empty <IEvent>().ToList())); }
public void Execute(Envelope <TCommand> command) { _processingCommandId = command.MessageId; var restoreAggregateCommand = new RestoreEventSourcedAggregateCommand <TIdentity, TSnapshot>(command.Body.Identity, command.Body.Version, command.MessageId); var restoreAggregateResult = CommandComposition .StartWith <RestoreEventSourcedAggregateCommand <TIdentity, TSnapshot>, RestoreAggregateCommandResult <TAggregate> >(restoreAggregateCommand) .Run(); _previouslyDispatchedMessages = restoreAggregateResult.PreviouslyDispatchedMessages; if (restoreAggregateResult.AlreadyDispatched) { var publishEvents = new PublishEventsCommand(restoreAggregateResult.NeedRedispatchEvents); CommandComposition .StartWith(publishEvents) .Run(); } else { var aggregate = restoreAggregateResult.Aggregate; IdempotentExecute(aggregate, command.Body); Persist(aggregate); } }