private async Task Save <T>(
            List <IDomainEvent> domainEvents,
            string operationId,
            Guid?correlationId,
            string contributor,
            CancellationToken cancellationToken)
            where T : class, IEventSourced
        {
            var envelopes = new List <Envelope <IDomainEvent> >(
                from domainEvent in domainEvents
                let messageId = Guid.NewGuid()
                                select new Envelope <IDomainEvent>(messageId, domainEvent, operationId, correlationId, contributor));

            var batch = new TableBatchOperation();

            foreach (Envelope <IDomainEvent> envelope in envelopes)
            {
                batch.Insert(PersistentEvent.Create(typeof(T), envelope, _serializer));
                batch.Insert(PendingEvent.Create(typeof(T), envelope, _serializer));
            }

            Guid sourceId = domainEvents.First().SourceId;

            if (correlationId.HasValue)
            {
                batch.Insert(Correlation.Create(typeof(T), sourceId, correlationId.Value));
            }

            try
            {
                await _eventTable.ExecuteBatch(batch, cancellationToken).ConfigureAwait(false);
            }
            catch (StorageException exception) when(correlationId.HasValue)
            {
                string filter = Correlation.GetFilter(typeof(T), sourceId, correlationId.Value);
                var    query  = new TableQuery <Correlation> {
                    FilterString = filter
                };

                if (await _eventTable.Any(query, cancellationToken).ConfigureAwait(false))
                {
                    throw new DuplicateCorrelationException(
                              typeof(T),
                              sourceId,
                              correlationId.Value,
                              exception);
                }

                throw;
            }
        }
示例#2
0
        private async Task InsertEventsAndCorrelation <T>(
            List <Envelope> envelopes,
            Guid?correlationId,
            CancellationToken cancellationToken)
            where T : class, IEventSourced
        {
            var batch = new TableBatchOperation();

            var  firstEvent = (IDomainEvent)envelopes.First().Message;
            Guid sourceId   = firstEvent.SourceId;

            foreach (Envelope envelope in envelopes)
            {
                batch.Insert(EventTableEntity.FromEnvelope <T>(envelope, _serializer));
            }

            if (correlationId.HasValue)
            {
                batch.Insert(CorrelationTableEntity.Create(typeof(T), sourceId, correlationId.Value));
            }

            try
            {
                await _eventTable.ExecuteBatchAsync(batch, cancellationToken).ConfigureAwait(false);
            }
            catch (StorageException exception) when(correlationId.HasValue)
            {
                string filter = CorrelationTableEntity.GetFilter(typeof(T), sourceId, correlationId.Value);
                var    query  = new TableQuery <CorrelationTableEntity>().Where(filter);

                if (await _eventTable.Any(query, cancellationToken))
                {
                    throw new DuplicateCorrelationException(
                              typeof(T),
                              sourceId,
                              correlationId.Value,
                              exception);
                }

                throw;
            }
        }