public async Task ItShouldStartWithNewSnapshot() { _snapshots .Load <Shopping>("customerId", "messageId") .Returns(Task.FromResult(new Snapshot( -1, "customerId", new Shopping() ))); _events .Load <Shopping>("customerId", "messageId", -1) .Returns(new Envelope[0].ToAsync()); await _events .Append <Shopping>(Arg.Do <IEnumerable <Envelope> >(envelopes => { var first = envelopes.First(); first.Sequence.ShouldBe(0); ((ProductChosen)first.Message).ShouldNotBeNull(); ((ProductChosen)first.Message).CustomerId.ShouldBe("customerId"); ((ProductChosen)first.Message).ProductId.ShouldBe("productId"); })); await _snapshots .Save <Shopping>(Arg.Do <Snapshot>(snapshot => { snapshot.Sequence.ShouldBe(0); snapshot.Identity.ShouldBe("customerId"); snapshot.Snap.ShouldBeOfType <Shopping>(); })); await new CommandHandler <Shopping>(_events, _snapshots, "customerId") .Handle(new ChooseProduct("customerId", "productId"), "messageId"); }
public async Task Handle(object cmd, string messageId = null) { if (null == _snapshot) { _snapshot = await _snapshots.Load <TInvariant>(_identity, messageId); await foreach (var envelope in _events.Load <TInvariant>(_identity, messageId, _snapshot.Sequence)) { _snapshot.Sequence++; _snapshot.Snap = ((IArrange <TInvariant>)_snapshot.Snap).Arrange(envelope.Message); } } _snapshot.Snap = await((IAct <TInvariant>)_snapshot.Snap).Act(cmd); var envelopes = ((IAct <TInvariant>)_snapshot.Snap) .Commit() .Select((evt, i) => new Envelope( _identity, typeof(TInvariant).Name, ++_snapshot.Sequence, evt ).CausedBy(messageId ?? Guid.NewGuid().ToString())) .ToArray(); if (!envelopes.Any()) { return; } await _events.Append <TInvariant>(envelopes); await _snapshots.Save <TInvariant>(_snapshot); }
/// <summary> /// Retrieve the aggregate of the specified <paramref name="aggregateType"/> and aggregate <paramref name="id"/>. /// </summary> /// <param name="aggregateType">The type of aggregate to retrieve.</param> /// <param name="id">The unique aggregate id.</param> public Aggregate Get(Type aggregateType, Guid id) { Verify.NotNull(aggregateType, nameof(aggregateType)); Verify.TypeDerivesFrom(typeof(Aggregate), aggregateType, nameof(aggregateType)); var aggregate = GetOrCreate(aggregateType, id); var originalAggregateVersion = aggregate.Version; var commits = eventStore.GetStream(id, aggregate.Version + 1); foreach (var commit in commits) { ApplyCommitToAggregate(commit, aggregate); } if (aggregate.Version - originalAggregateVersion >= snapshotInterval) { snapshotStore.Save(new Snapshot(aggregate.Id, aggregate.Version, aggregate)); } return(aggregate); }
/// <summary> /// Adds a new snapshot to the snapshot store, keeping all existing snapshots. /// </summary> /// <param name="snapshot">The snapshot to append to the snapshot store.</param> public void Save(Snapshot snapshot) { snapshotStore.Save(snapshot); if (snapshot.Version == 1) { statistics.IncrementInsertCount(); } else { statistics.IncrementUpdateCount(); } }