コード例 #1
0
        public virtual async Task <T> GetByIdAsync <T>(Guid id) where T : AggregateRoot
        {
            T item = default(T);

            var isSnapshottable = typeof(ISnapshottable).IsAssignableFrom(typeof(T));

            Snapshot.Snapshot snapshot = null;

            if ((isSnapshottable) && (SnapshotStorageProvider != null))
            {
                snapshot = await SnapshotStorageProvider.GetSnapshotAsync(typeof(T), id);
            }

            if (snapshot != null)
            {
                item = ReflectionHelper.CreateInstance <T>();
                ((ISnapshottable)item).ApplySnapshot(snapshot);
                var events = await EventStorageProvider.GetEventsAsync(typeof(T), id, snapshot.Version + 1, int.MaxValue);

                item.LoadsFromHistory(events);
            }
            else
            {
                var events = (await EventStorageProvider.GetEventsAsync(typeof(T), id, 0, int.MaxValue)).ToList();

                if (!events.Any())
                {
                    return(item);
                }
                item = ReflectionHelper.CreateInstance <T>();
                item.LoadsFromHistory(events);
            }

            return(item);
        }
コード例 #2
0
        private async Task CommitChanges(AggregateRoot aggregate)
        {
            var expectedVersion = aggregate.LastCommittedVersion;

            IEvent item = await EventStorageProvider.GetLastEventAsync(aggregate.GetType(), aggregate.Id);

            if ((item != null) && (expectedVersion == (int)AggregateRoot.StreamState.NoStream))
            {
                throw new AggregateCreationException($"Aggregate {item.CorrelationId} can't be created as it already exists with version {item.TargetVersion + 1}");
            }
            if ((item != null) && ((item.TargetVersion + 1) != expectedVersion))
            {
                throw new ConcurrencyException($"Aggregate {item.CorrelationId} has been modified externally and has an updated state. Can't commit changes.");
            }

            var changesToCommit = aggregate.GetUncommittedChanges().ToList();

            //perform pre commit actions
            foreach (var e in changesToCommit)
            {
                DoPreCommitTasks(e);
            }

            //CommitAsync events to storage provider
            await EventStorageProvider.CommitChangesAsync(aggregate);

            //Publish to event publisher asynchronously
            foreach (var e in changesToCommit)
            {
                await EventPublisher.PublishAsync(e);
            }

            //If the Aggregate implements snaphottable
            var snapshottable = aggregate as ISnapshottable;

            if ((snapshottable != null) && (SnapshotStorageProvider != null))
            {
                //Every N events we save a snapshot
                if ((aggregate.CurrentVersion >= SnapshotStorageProvider.SnapshotFrequency) &&
                    (
                        (changesToCommit.Count >= SnapshotStorageProvider.SnapshotFrequency) ||
                        (aggregate.CurrentVersion % SnapshotStorageProvider.SnapshotFrequency < changesToCommit.Count) ||
                        (aggregate.CurrentVersion % SnapshotStorageProvider.SnapshotFrequency == 0)
                    )
                    )
                {
                    await SnapshotStorageProvider.SaveSnapshotAsync(aggregate.GetType(), snapshottable.TakeSnapshot());
                }
            }

            aggregate.MarkChangesAsCommitted();
        }