예제 #1
0
        public async Task SaveAsync(Type aggregateType, IAggregateIdentity aggregateId, ICollection <IEvent> events, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (events.Count == 0)
            {
                return;
            }

            var partition = GetPartition(aggregateType, aggregateId);

            lock (eventStore)
            {
                Tuple <ETag, List <EventEntity> > eTaggedEvents;
                if (eventStore.TryGetValue(partition, out eTaggedEvents))
                {
                    // Check my last ETag against the current ETag
                    var  dbETag = eTaggedEvents.Item1;
                    ETag myETag;
                    if (idToETag.TryGetValue(aggregateId, out myETag) && myETag != dbETag)
                    {
                        throw new Ddd.Domain.Exceptions.ConcurrencyException(aggregateType, aggregateId);
                    }

                    var eventsEntities = eTaggedEvents.Item2;
                    var lastVer        = eventsEntities.Count;

                    eventsEntities.AddRange(events.Select(e => ToEventEntity(e, ++lastVer)));

                    var eTag = ETag.NewGuid();
                    eventStore[partition] = new Tuple <ETag, List <EventEntity> >(
                        eTag,
                        eventsEntities);
                    idToETag[aggregateId] = eTag; // Remeber current ETag
                }
                else
                {
                    var eTag           = ETag.NewGuid();
                    var lastVer        = 0;
                    var eventsEntities = events.Select(e => ToEventEntity(e, ++lastVer)).ToList();
                    eventStore.Add(partition, new Tuple <ETag, List <EventEntity> >(
                                       eTag,
                                       eventsEntities));
                    idToETag.Add(aggregateId, eTag); // Remeber current ETag
                }
            }

            await bus.PublishAsync(events);
        }