private int GetActualVersion(
            EventDescriptors eventDescriptors, 
            int expectedVersion,
            IEnumerable<Event> events,
            IConcurrencyConflictResolver conflictResolver)
        {
            var actualVersion = eventDescriptors[eventDescriptors.Count() - 1].Version;

            if (actualVersion != expectedVersion && expectedVersion != -1)
            {
                var potentialConflictingEvents =
                    eventDescriptors
                    .Where(e => e.Version > expectedVersion)
                    .Select(e => e.EventData);
                if (AnyEventsConflict(events, potentialConflictingEvents, conflictResolver))
                {
                    throw new EventStoreConcurrencyException();
                }
                else
                {
                    return actualVersion;
                }
            }

            return expectedVersion;
        }
        public void SaveEvents(
            Guid aggregateId, 
            IEnumerable<Event> events, 
            int expectedVersion,
            IConcurrencyConflictResolver conflictResolver)
        {
            lock (_saveLock)
            {
                var eventDescriptors =
                    _database.Get(aggregateId.ToString());
                var actualVersion = expectedVersion;

                if (eventDescriptors == null)
                {
                    eventDescriptors = new EventDescriptors {Id = aggregateId};
                    _database.Put(eventDescriptors);
                }
                else
                {
                    actualVersion = GetActualVersion(
                        eventDescriptors,
                        expectedVersion,
                        events,
                        conflictResolver);
                }

                var i = actualVersion;
                foreach (var @event in events)
                {
                    i++;
                    @event.Version = i;
                    @event.AggregateId = aggregateId;
                    @event.Id = Guid.NewGuid();
                    eventDescriptors.Add(
                        new EventDescriptor(aggregateId, @event, i));
                    _publisher.Publish(@event);
                }

                _database.Update(eventDescriptors);
            }
        }
        private bool AnyEventsConflict(
            IEnumerable<Event> events,
            IEnumerable<Event> conflictingEvents,
            IConcurrencyConflictResolver conflictResolver)
        {
            if (conflictResolver == null)
            {
                return true;
            }

            var eventTypes = events.Select(e => e.GetType());
            var conflictingEventTypes = conflictingEvents.Select(e => e.GetType());
            return eventTypes.Any(eventType => 
                conflictResolver.ConflictsWith(
                    eventType, 
                    conflictingEventTypes));
        }
Esempio n. 4
0
        public async Task <IEventStore> GetEventStore(Assembly[] contractsRegistryAssemblies, IConcurrencyConflictResolver resolver = null)
        {
            if (!_databaseCreated)
            {
                await CreateDatabase(GetLocation());
            }

            var builder = new EventStoreBuilder()
                          .WithDefaultContractsRegistry(contractsRegistryAssemblies)
                          .WithMsSqlPersistor(ConnectionString, x =>
            {
                x.Initialize();
            })
                          .WithSerializer(new JilSerializer());

            if (resolver != null)
            {
                builder.WithConcurrencyConflictResolver(resolver);
            }

            return(builder.Build());
        }
 protected AggregateRoot()
 {
     _conflictResolver = new ConcurrencyConflictResolver();
     _changes = new List<Event>();
     _entities = new List<object>();
 }
Esempio n. 6
0
 protected async Task <IEventStore> GetEventStore(IConcurrencyConflictResolver resolver = null)
 {
     return(await _dbInstance.GetEventStore(new[] { typeof(TestsBase).Assembly }, resolver));
 }