public void Should_be_able_to_raise_concurrency_exception_if_satisfied_by_specification()
        {
            var specification = new Mock <IConcurrenyExceptionSpecification>();
            var repository    = new Mock <IPrimitiveEventRepository>();

            repository.Setup(m => m.Save(It.IsAny <PrimitiveEvent>())).Throws <Exception>();

            var observer = new SavePrimitiveEventsObserver(
                repository.Object,
                new Mock <ISerializer>().Object,
                specification.Object);

            var pipeline = new Pipeline();

            pipeline.State.SetEventStream(new EventStream(Guid.NewGuid(), new Mock <IEventMethodInvoker>().Object));
            pipeline.State.SetEventEnvelopes(new List <EventEnvelope>
            {
                new EventEnvelope()
            });

            var pipelineEvent = new OnSavePrimitiveEvents();

            pipelineEvent.Reset(pipeline);

            specification.Setup(m => m.IsSatisfiedBy(It.IsAny <Exception>())).Returns(false);

            Assert.Throws <NullReferenceException>(() => observer.Execute(pipelineEvent)); // since mock serializer is returning null

            specification.Setup(m => m.IsSatisfiedBy(It.IsAny <Exception>())).Returns(true);

            Assert.Throws <EventStreamConcurrencyException>(() => observer.Execute(pipelineEvent));
        }
        public void Execute(OnSavePrimitiveEvents pipelineEvent)
        {
            var state          = pipelineEvent.Pipeline.State;
            var eventStream    = state.GetEventStream();
            var eventEnvelopes = state.GetEventEnvelopes();

            Guard.AgainstNull(eventStream, nameof(eventStream));
            Guard.AgainstNull(eventEnvelopes, nameof(eventEnvelopes));

            var version = -1;

            try
            {
                foreach (var eventEnvelope in eventEnvelopes)
                {
                    version = eventEnvelope.Version;

                    _primitiveEventRepository.Save(new PrimitiveEvent
                    {
                        Id             = eventStream.Id,
                        EventEnvelope  = _serializer.Serialize(eventEnvelope).ToBytes(),
                        EventId        = eventEnvelope.EventId,
                        EventType      = eventEnvelope.EventType,
                        IsSnapshot     = eventEnvelope.IsSnapshot,
                        Version        = version,
                        DateRegistered = eventEnvelope.EventDate
                    });
                }
            }
            catch (Exception ex)
            {
                if (_concurrencyExceptionSpecification.IsSatisfiedBy(ex))
                {
                    throw new EventStreamConcurrencyException(
                              string.Format(Resources.EventStreamConcurrencyException, eventStream.Id, version), ex);
                }

                throw;
            }
        }