private bool TryGetFromSnapshot(string aggregateRootId, Type aggregateRootType, out IAggregateRoot aggregateRoot) { aggregateRoot = _aggregateSnapshotter.RestoreFromSnapshot(aggregateRootType, aggregateRootId); if (aggregateRoot == null) { return(false); } if (aggregateRoot.GetType() != aggregateRootType || aggregateRoot.UniqueId != aggregateRootId) { throw new Exception(string.Format("AggregateRoot recovery from snapshot is invalid as the aggregateRootType or aggregateRootId is not matched. Snapshot: [aggregateRootType:{0},aggregateRootId:{1}], expected: [aggregateRootType:{2},aggregateRootId:{3}]", aggregateRoot.GetType(), aggregateRoot.UniqueId, aggregateRootType, aggregateRootId)); } var aggregateRootTypeName = _typeNameProvider.GetTypeName(aggregateRootType); var eventStreamsAfterSnapshot = _eventStore.QueryAggregateEvents(aggregateRootId, aggregateRootTypeName, aggregateRoot.Version + 1, int.MaxValue); aggregateRoot.ReplayEvents(eventStreamsAfterSnapshot); return(true); }
private bool TryGetFromSnapshot(string aggregateRootId, Type aggregateRootType, out IAggregateRoot aggregateRoot) { aggregateRoot = null; var snapshot = _snapshotStore.GetLastestSnapshot(aggregateRootId, aggregateRootType); if (snapshot == null) { return(false); } aggregateRoot = _snapshotter.RestoreFromSnapshot(snapshot); if (aggregateRoot == null) { return(false); } if (aggregateRoot.UniqueId != aggregateRootId) { throw new Exception(string.Format("Aggregate root restored from snapshot not valid as the aggregate root id not matched. Snapshot aggregate root id:{0}, expected aggregate root id:{1}", aggregateRoot.UniqueId, aggregateRootId)); } var aggregateRootTypeCode = _aggregateRootTypeCodeProvider.GetTypeCode(aggregateRootType); var eventStreamsAfterSnapshot = _eventStore.QueryAggregateEvents(aggregateRootId, aggregateRootTypeCode, snapshot.Version + 1, int.MaxValue); aggregateRoot.ReplayEvents(eventStreamsAfterSnapshot); return(true); }
private bool TryGetFromSnapshot(string aggregateRootId, Type aggregateRootType, out IAggregateRoot aggregateRoot) { aggregateRoot = _aggregateSnapshotter.RestoreFromSnapshot(aggregateRootType, aggregateRootId); if (aggregateRoot == null) return false; if (aggregateRoot.GetType() != aggregateRootType || aggregateRoot.UniqueId != aggregateRootId) { throw new Exception(string.Format("AggregateRoot recovery from snapshot is invalid as the aggregateRootType or aggregateRootId is not matched. Snapshot: [aggregateRootType:{0},aggregateRootId:{1}], expected: [aggregateRootType:{2},aggregateRootId:{3}]", aggregateRoot.GetType(), aggregateRoot.UniqueId, aggregateRootType, aggregateRootId)); } var aggregateRootTypeName = _typeNameProvider.GetTypeName(aggregateRootType); var eventStreamsAfterSnapshot = _eventStore.QueryAggregateEvents(aggregateRootId, aggregateRootTypeName, aggregateRoot.Version + 1, int.MaxValue); aggregateRoot.ReplayEvents(eventStreamsAfterSnapshot); return true; }
private bool TryGetFromSnapshot(string aggregateRootId, Type aggregateRootType, out IAggregateRoot aggregateRoot) { aggregateRoot = null; var snapshot = _snapshotStore.GetLastestSnapshot(aggregateRootId, aggregateRootType); if (snapshot == null) return false; aggregateRoot = _snapshotter.RestoreFromSnapshot(snapshot); if (aggregateRoot == null) return false; if (aggregateRoot.UniqueId != aggregateRootId) { throw new Exception(string.Format("Aggregate root restored from snapshot not valid as the aggregate root id not matched. Snapshot aggregate root id:{0}, expected aggregate root id:{1}", aggregateRoot.UniqueId, aggregateRootId)); } var aggregateRootTypeCode = _aggregateRootTypeCodeProvider.GetTypeCode(aggregateRootType); var eventStreamsAfterSnapshot = _eventStore.QueryAggregateEvents(aggregateRootId, aggregateRootTypeCode, snapshot.Version + 1, int.MaxValue); aggregateRoot.ReplayEvents(eventStreamsAfterSnapshot); return true; }
/// <summary> /// Save /// </summary> /// <param name="snapshotHeaders"></param> /// <returns></returns> public async Task SaveAsync(IEnumerable <AggregateSnapshotHeader> snapshotHeaders) { var queue = new ConcurrentQueue <AggregateSnapshotData>(); foreach (var snapshotHeader in snapshotHeaders) { try { var aggregateRootType = _typeNameProvider.GetType(snapshotHeader.AggregateRootTypeName); IAggregateRoot aggregateRoot = null; IEnumerable <DomainEventStream> eventStreams = null; var lastSnapshotData = await _snapshotStore.FindLatestAsync(snapshotHeader.AggregateRootId, snapshotHeader.AggregateRootTypeName); if (lastSnapshotData != null) { try { using (var ms = new MemoryStream()) { await ms.WriteAsync(lastSnapshotData.Data, 0, lastSnapshotData.Data.Length); await ms.FlushAsync(); ms.Position = 0; aggregateRoot = _binaryFormatter.Deserialize(ms) as IAggregateRoot; } } catch { aggregateRoot = null; } } if (aggregateRoot == null) { // 无快照 aggregateRoot = _aggregateRootFactory.CreateAggregateRoot(aggregateRootType); eventStreams = await _eventStore.QueryAggregateEventsAsync(snapshotHeader.AggregateRootId, snapshotHeader.AggregateRootTypeName, 1, snapshotHeader.Version); } else { eventStreams = await _eventStore.QueryAggregateEventsAsync(snapshotHeader.AggregateRootId, snapshotHeader.AggregateRootTypeName, lastSnapshotData.Version + 1, snapshotHeader.Version); } if (eventStreams != null && eventStreams.Any()) { aggregateRoot.ReplayEvents(eventStreams); using (var ms = new MemoryStream()) { _binaryFormatter.Serialize(ms, aggregateRoot); await ms.FlushAsync(); ms.Position = 0; byte[] buffer = new byte[ms.Length]; await ms.ReadAsync(buffer, 0, buffer.Length); queue.Enqueue(new AggregateSnapshotData(snapshotHeader.AggregateRootId, snapshotHeader.AggregateRootTypeName, aggregateRoot.Version, buffer)); } } } catch (Exception ex) { _logger.Error($"Save snapshot fail:{ex.Message}. AggregateRootId={snapshotHeader.AggregateRootId},AggregateRootTypeName={snapshotHeader.AggregateRootTypeName}", ex); } } var snapshotDataList = new List <AggregateSnapshotData>(); while (queue.TryDequeue(out AggregateSnapshotData snapshotData)) { snapshotDataList.Add(snapshotData); if (snapshotDataList.Count == _batchSaveSize) { try { await _snapshotStore.BatchSaveAsync(snapshotDataList); } catch (Exception ex) { _logger.Error($"Save snapshot fail:{ex.Message}.", ex); } finally { snapshotDataList.Clear(); } } } }
private bool TryGetFromCompatibleAggregateStore(string aggregateRootId, Type aggregateRootType, ICompatibleStoreHandler aggregateInitHandler, CompatibleStyle compatibleStyle, out IAggregateRoot aggregateRoot) { aggregateRoot = null; var aggregateRootTypeCode = _aggregateRootTypeCodeProvider.GetTypeCode(aggregateRootType); if (compatibleStyle == CompatibleStyle.RepositoryOnly) { // Replay Repository Aggregate Init Event DomainEventStream aggregateInitEvent = aggregateInitHandler.GetAggregateRestoreEventStream(aggregateRootId); if (aggregateInitEvent != null) { if (aggregateInitEvent.AggregateRootId != aggregateRootId) { throw new Exception(string.Format("DomainEventStream.AggregateRootId error: {0}, expected aggregate root id:{1}", aggregateInitEvent.AggregateRootId, aggregateRootId)); } aggregateRoot = _aggregateRootFactory.CreateAggregateRoot(aggregateRootType); aggregateRoot.RestoreFromEvents(aggregateInitEvent); return(true); } return(false); } else if (compatibleStyle == CompatibleStyle.RepositoryThenEventSourcing) { var versionStart = minVersion; // Replay Repository Aggregate Init Event //IDomainEvent aggregateInitEvent = _compatibleAggregateStore.GetAggregateInitEvent(aggregateRootType, aggregateRootId); DomainEventStream aggregateInitEvent = aggregateInitHandler.GetAggregateRestoreEventStream(aggregateRootId); if (aggregateInitEvent != null) { if (aggregateInitEvent.AggregateRootId != aggregateRootId) { throw new Exception(string.Format("DomainEventStream.AggregateRootId error: {0}, expected aggregate root id:{1}", aggregateInitEvent.AggregateRootId, aggregateRootId)); } aggregateRoot = _aggregateRootFactory.CreateAggregateRoot(aggregateRootType); aggregateRoot.RestoreFromEvents(aggregateInitEvent); versionStart = aggregateInitEvent.Version + 1; } // Replay Event Sourcing Events var eventStreams = _eventStore.QueryAggregateEvents(aggregateRootId, aggregateRootTypeCode, versionStart, maxVersion); if (eventStreams == null || !eventStreams.Any()) { if (aggregateRoot != null) { return(true); } else { return(false); } } aggregateRoot.ReplayEvents(eventStreams); return(true); } else //if(compatibleStyle == CompatibleAggregateInitStyle.EventSourcingOnly) { // Replay Event Sourcing Events var versionStart = minVersion; var eventStreams = _eventStore.QueryAggregateEvents(aggregateRootId, aggregateRootTypeCode, versionStart, maxVersion); if (eventStreams == null || !eventStreams.Any()) { return(false); } aggregateRoot = _aggregateRootFactory.CreateAggregateRoot(aggregateRootType); aggregateRoot.ReplayEvents(eventStreams); return(true); } }