protected override async Task <ReadModelUpdateResult <TReadModel> > UpdateAsync(
            IReadModelContext readModelContext,
            IReadOnlyCollection <IDomainEvent> domainEvents,
            ReadModelEnvelope <TReadModel> readModelEnvelope,
            CancellationToken cancellationToken)
        {
            var readModel = readModelEnvelope.ReadModel;

            if (readModel == null)
            {
                readModel = await ReadModelFactory.CreateAsync(
                    readModelEnvelope.ReadModelId,
                    cancellationToken)
                            .ConfigureAwait(false);
            }

            await ReadModelDomainEventApplier.UpdateReadModelAsync(
                readModel,
                domainEvents,
                readModelContext,
                cancellationToken)
            .ConfigureAwait(false);

            return(readModelEnvelope.AsModifedResult(
                       readModel,
                       readModelEnvelope.Version.GetValueOrDefault() + 1 // the best we can do
                       ));
        }
示例#2
0
        protected override async Task <ReadModelEnvelope <TReadModel> > UpdateAsync(
            IReadModelContext readModelContext,
            IReadOnlyCollection <IDomainEvent> domainEvents,
            ReadModelEnvelope <TReadModel> readModelEnvelope,
            CancellationToken cancellationToken)
        {
            var readModel = readModelEnvelope.ReadModel ?? new TReadModel();
            await ReadModelDomainEventApplier.UpdateReadModelAsync(readModel, domainEvents, readModelContext, cancellationToken).ConfigureAwait(false);

            return(ReadModelEnvelope <TReadModel> .With(readModel));
        }
示例#3
0
        protected override async Task <ReadModelEnvelope <TReadModel> > UpdateAsync(
            IReadModelContext readModelContext,
            IReadOnlyCollection <IDomainEvent> domainEvents,
            ReadModelEnvelope <TReadModel> readModelEnvelope,
            CancellationToken cancellationToken)
        {
            var readModel = readModelEnvelope.ReadModel ?? await ReadModelFactory.CreateAsync(readModelEnvelope.ReadModelId, cancellationToken).ConfigureAwait(false);

            await ReadModelDomainEventApplier.UpdateReadModelAsync(readModel, domainEvents, readModelContext, cancellationToken).ConfigureAwait(false);

            var readModelVersion = domainEvents.Max(e => e.AggregateSequenceNumber);

            return(ReadModelEnvelope <TReadModel> .With(readModelEnvelope.ReadModelId, readModel, readModelVersion));
        }
示例#4
0
        private async Task <ReadModelUpdateResult <TReadModel> > ApplyUpdatesAsync(
            IReadModelContext readModelContext,
            IReadOnlyCollection <IDomainEvent> domainEvents,
            ReadModelEnvelope <TReadModel> readModelEnvelope,
            CancellationToken cancellationToken)
        {
            TReadModel readModel = await GetOrCreateReadModel(readModelEnvelope, cancellationToken);

            await ReadModelDomainEventApplier
            .UpdateReadModelAsync(readModel, domainEvents, readModelContext, cancellationToken)
            .ConfigureAwait(false);

            var readModelVersion = Math.Max(
                domainEvents.Max(e => e.AggregateSequenceNumber),
                readModelEnvelope.Version.GetValueOrDefault());

            return(readModelEnvelope.AsModifedResult(readModel, readModelVersion));
        }
        protected override async Task <ReadModelUpdateResult <TReadModel> > UpdateAsync(
            IReadModelContext readModelContext,
            IReadOnlyCollection <IDomainEvent> domainEvents,
            ReadModelEnvelope <TReadModel> readModelEnvelope,
            CancellationToken cancellationToken)
        {
            if (!domainEvents.Any())
            {
                throw new ArgumentException("No domain events");
            }

            var expectedVersion = domainEvents.Min(d => d.AggregateSequenceNumber) - 1;
            var version         = readModelEnvelope.Version;

            if (!version.HasValue || expectedVersion == version)
            {
                Log.Verbose(() => $"Read model '{typeof(TReadModel)}' with ID '{readModelEnvelope.ReadModelId}' has version {expectedVersion} (or none), applying events");
                return(await base.UpdateAsync(
                           readModelContext,
                           domainEvents,
                           readModelEnvelope,
                           cancellationToken)
                       .ConfigureAwait(false));
            }
            if (expectedVersion < version.Value)
            {
                Log.Verbose(() => $"Read model '{typeof(TReadModel)}' with ID '{readModelEnvelope.ReadModelId}' already has version {version.Value} compared to {expectedVersion}, skipping");
                return(readModelEnvelope.AsUnmodifedResult());
            }

            TReadModel readModel;

            if (readModelEnvelope.ReadModel == null)
            {
                readModel = await ReadModelFactory.CreateAsync(
                    readModelEnvelope.ReadModelId,
                    cancellationToken)
                            .ConfigureAwait(false);
            }
            else
            {
                readModel = readModelEnvelope.ReadModel;
            }

            // Apply missing events
            var identity      = domainEvents.Cast <IDomainEvent <TAggregate, TIdentity> >().First().AggregateIdentity;
            var missingEvents = await _eventStore.LoadEventsAsync <TAggregate, TIdentity>(
                identity,
                (int)version.Value + 1,
                cancellationToken)
                                .ConfigureAwait(false);

            Log.Verbose(() => $"Read model '{typeof(TReadModel)}' with ID '{readModelEnvelope.ReadModelId}' is missing some events {version.Value} < {expectedVersion}, adding them (got {missingEvents.Count} events)");

            await ReadModelDomainEventApplier.UpdateReadModelAsync(
                readModel,
                missingEvents,
                readModelContext,
                cancellationToken)
            .ConfigureAwait(false);

            version = domainEvents.Max(e => e.AggregateSequenceNumber);

            return(readModelEnvelope.AsModifedResult(
                       readModel,
                       version));
        }