private List <IAggregateEvent> GetPendingEvents <T>(ISyncState syncState, IList <IAggregateEvent> remoteEvents) where T : class, IAggregateRoot, new() { if (syncState.LastSyncedVersion == 0) { // if we've never synced, then this aggregate must have been created locally, any events either in // the event store or from pending commands are pending return(this.localEventStore.GetAllEvents(syncState.Identity).ToList()); } // if we have synced the aggregate at least once, then we need to get events from pending commands var pendingCommandsToExecute = this.pendingCommands.PendingCommandsForAggregate(syncState.Identity).ToList(); if (pendingCommandsToExecute.Count == 0) { return(new List <IAggregateEvent>()); } var aggregate = new T(); aggregate.Identity = syncState.Identity; ((IEventSourced)aggregate).LoadFromEvents(remoteEvents); var exec = new ExecutingCommandExecutor(aggregate); exec.Execute(pendingCommandsToExecute, 0); if (this.snapshotRepository != null && aggregate is ISnapshotSupport) { this.snapshotRepository.Save(((ISnapshotSupport)aggregate).GetSnapshot()); } return(aggregate.UncommittedEvents.ToList()); }
public void Execute(IList <IAggregateCommand> commands, int expectedVersion) { if (!commands.Any()) { return; } var rootId = commands.First().AggregateId; if (commands.Any(x => x.AggregateId != rootId)) { throw new InvalidOperationException("Can only execute commands for a single aggregate at a time"); } var root = this.repository.GetById(rootId); if (root == null) { root = this.repository.New(); root.Identity = rootId; } if (expectedVersion != 0) { // if we using this command executor multiple times for the same aggregate, when we invoke it we will often have the // verion of the roor prior to the first invocation. Consequently when we check the expected version the second time, // we have a different version and we get an exception. This is supposed to handle that case by remembering what the // version of the root was when we first saw it. var rootVersion = root.Version; if (this.versions.ContainsKey(root.Identity)) { rootVersion = this.versions[root.Identity]; } if (rootVersion != expectedVersion) { throw new InvalidOperationException(string.Format("Not Expected Version {0}, {1}", expectedVersion, root.Version)); } } var exec = new ExecutingCommandExecutor(root); exec.Execute(commands, expectedVersion); this.repository.Save(root); if (expectedVersion != 0 && !this.versions.ContainsKey(root.Identity)) { this.versions[root.Identity] = expectedVersion; } }
public void Execute(IList<IAggregateCommand> commands, int expectedVersion) { if (!commands.Any()) { return; } var rootId = commands.First().AggregateId; if (commands.Any(x => x.AggregateId != rootId)) { throw new InvalidOperationException("Can only execute commands for a single aggregate at a time"); } var root = this.repository.GetById(rootId); if (root == null) { root = this.repository.New(); root.Identity = rootId; } if (expectedVersion != 0) { // if we using this command executor multiple times for the same aggregate, when we invoke it we will often have the // verion of the roor prior to the first invocation. Consequently when we check the expected version the second time, // we have a different version and we get an exception. This is supposed to handle that case by remembering what the // version of the root was when we first saw it. var rootVersion = root.Version; if (this.versions.ContainsKey(root.Identity)) { rootVersion = this.versions[root.Identity]; } if (rootVersion != expectedVersion) { throw new InvalidOperationException(string.Format("Not Expected Version {0}, {1}", expectedVersion, root.Version)); } } var exec = new ExecutingCommandExecutor(root); exec.Execute(commands, expectedVersion); this.repository.Save(root); if (expectedVersion != 0 && !this.versions.ContainsKey(root.Identity)) { this.versions[root.Identity] = expectedVersion; } }