public void GivenStreamOfEvents_WhenAggregateStreamIsCalled_ThenChangesAreAppliedProperly()
        {
            var streamId = EventStore.StartStream <TaskList>();

            //1. First Task Was Created
            var task1Id = Guid.NewGuid();

            EventStore.Append(streamId, new TaskCreated {
                TaskId = task1Id, Description = "Description"
            });
            Session.SaveChanges();

            var taskList = EventStore.AggregateStream <TaskList>(streamId);

            taskList.List.Should().Have.Count.EqualTo(1);
            taskList.List.Single().TaskId.Should().Be.EqualTo(task1Id);
            taskList.List.Single().Description.Should().Be.EqualTo("Description");

            //2. First Task Description Was Changed
            EventStore.Append(streamId, new TaskUpdated {
                TaskId = task1Id, Description = "New Description"
            });
            Session.SaveChanges();

            taskList = EventStore.AggregateStream <TaskList>(streamId);

            taskList.List.Should().Have.Count.EqualTo(1);
            taskList.List.Single().TaskId.Should().Be.EqualTo(task1Id);
            taskList.List.Single().Description.Should().Be.EqualTo("New Description");

            //3. Two Other tasks were added
            EventStore.Append(streamId, new TaskCreated {
                TaskId = Guid.NewGuid(), Description = "Description2"
            },
                              new TaskCreated {
                TaskId = Guid.NewGuid(), Description = "Description3"
            });
            Session.SaveChanges();

            taskList = EventStore.AggregateStream <TaskList>(streamId);

            taskList.List.Should().Have.Count.EqualTo(3);
            taskList.List.Select(t => t.Description)
            .Should()
            .Have.SameSequenceAs("New Description", "Description2", "Description3");


            //4. First task was removed
            EventStore.Append(streamId, new TaskRemoved {
                TaskId = task1Id
            });
            Session.SaveChanges();

            taskList = EventStore.AggregateStream <TaskList>(streamId);

            taskList.List.Should().Have.Count.EqualTo(2);
            taskList.List.Select(t => t.Description)
            .Should()
            .Have.SameSequenceAs("Description2", "Description3");
        }
    public void GivenAggregateWithCompositeId_WhenAppendedEvent_LiveAndInlineAggregationWorks()
    {
        var seatId     = new SeatId(Guid.NewGuid());
        var customerId = new CustomerId(Guid.NewGuid());

        var reservation = Reservation.CreateTentative(seatId, customerId);
        var @event      = reservation.DequeueUncommittedEvents().Single();

        //1. Create events
        EventStore.Append(reservation.AggregateId, @event);

        Session.SaveChanges();

        //2. Get live aggregation
        var issuesListFromLiveAggregation = EventStore.AggregateStream <Reservation>(reservation.AggregateId);

        //3. Get inline aggregation
        var issuesListFromInlineAggregation = Session.Load <Reservation>(reservation.AggregateId);

        //4. Get inline aggregation through linq
        var reservationId = reservation.Id;

        var issuesListFromInlineAggregationFromLinq = Session.Query <Reservation>().SingleOrDefault(r => r.Id.Value == reservationId.Value);
        var issuesListFromInlineAggregationFromLinqWithAggregateId = Session.Query <Reservation>().SingleOrDefault(r => r.AggregateId == reservationId.Value);

        issuesListFromLiveAggregation.Should().NotBeNull();
        issuesListFromInlineAggregation.Should().NotBeNull();
        issuesListFromInlineAggregationFromLinq.Should().NotBeNull();
        issuesListFromInlineAggregationFromLinqWithAggregateId.Should().NotBeNull();

        issuesListFromLiveAggregation !.AggregateId.Should().Be(reservationId.Value);
        issuesListFromLiveAggregation !.AggregateId.Should().Be(reservationId.Value);
        issuesListFromInlineAggregationFromLinq !.AggregateId.Should().Be(reservationId.Value);
        issuesListFromInlineAggregationFromLinqWithAggregateId !.AggregateId.Should().Be(reservationId.Value);
    }
        static void Save(ShoppingCart shoppingCart, EventStore eventStore)
        {
            var eventsToStore = shoppingCart.DequeueUncommittedEvents().ToList();

            eventStore.Append(eventsToStore);
            eventStore.Save();
        }
        public async Task ReturnAllEventsInThePersistence()
        {
            const string streamName = "streamName";
            var          underTest  = new EventStore(_persistence);

            await underTest.Append(streamName, EventStore.StreamPositions.Any, new byte[0], new byte[0]);

            await underTest.Append(streamName, EventStore.StreamPositions.Any, new byte[0], new byte[0]);

            await underTest.Append(streamName, EventStore.StreamPositions.Any, new byte[0], new byte[0]);

            var events = _persistence.GetAllEvents();
            var total  = await events.CountAsync();

            Assert.Equal(3, total);
        }
示例#5
0
        public void GivenStreamOfEvents_WhenAggregateStreamIsCalled_ThenChangesAreAppliedProperly()
        {
            var streamId = Guid.NewGuid();

            //1. First Issue Was Created
            var issue1Id = Guid.NewGuid();

            EventStore.Append(streamId, new IssueCreated {
                IssueId = issue1Id, Description = "Description"
            });
            Session.SaveChanges();

            var issuesList = EventStore.AggregateStream <IssuesList>(streamId);

            issuesList.List.Should().Have.Count.EqualTo(1);
            issuesList.List.Single().IssueId.Should().Be.EqualTo(issue1Id);
            issuesList.List.Single().Description.Should().Be.EqualTo("Description");

            //2. First Issue Description Was Changed
            EventStore.Append(streamId, new IssueUpdated {
                IssueId = issue1Id, Description = "New Description"
            });
            Session.SaveChanges();

            issuesList = EventStore.AggregateStream <IssuesList>(streamId);

            issuesList.List.Should().Have.Count.EqualTo(1);
            issuesList.List.Single().IssueId.Should().Be.EqualTo(issue1Id);
            issuesList.List.Single().Description.Should().Be.EqualTo("New Description");

            //3. Two Other tasks were added
            EventStore.Append(streamId, new IssueCreated {
                IssueId = Guid.NewGuid(), Description = "Description2"
            },
                              new IssueCreated {
                IssueId = Guid.NewGuid(), Description = "Description3"
            });
            Session.SaveChanges();

            issuesList = EventStore.AggregateStream <IssuesList>(streamId);

            issuesList.List.Should().Have.Count.EqualTo(3);
            issuesList.List.Select(t => t.Description)
            .Should()
            .Have.SameSequenceAs("New Description", "Description2", "Description3");

            //4. First issue was removed
            EventStore.Append(streamId, new IssueRemoved {
                IssueId = issue1Id
            });
            Session.SaveChanges();

            issuesList = EventStore.AggregateStream <IssuesList>(streamId);

            issuesList.List.Should().Have.Count.EqualTo(2);
            issuesList.List.Select(t => t.Description)
            .Should()
            .Have.SameSequenceAs("Description2", "Description3");
        }
        public async Task WriteEventWhenStreamNotCreatedAndPositionIsCreate()
        {
            var eventPersistence = _persistence;
            var underTest        = new EventStore(eventPersistence);
            var result           = await underTest.Append("streamName", EventStore.StreamPositions.Create, new byte[0], new byte[0]);

            Assert.Equal(1, result.NextPosition);
        }
        public async Task ThrowUnexpectedPositionWhenStreamExistsAndPositionWrongOnAppend()
        {
            const string streamName = "streamName";
            await _persistence.AppendEvent(new IEventPersistence.Event(streamName, 0, new byte[0], new byte[0]));

            var underTest = new EventStore(_persistence);

            await Assert.ThrowsAsync <UnexpectedStreamPositionException>(() =>
                                                                         underTest.Append(streamName, 2, new byte[0], new byte[0]));
        }
        public async Task ReturnEventsByStream()
        {
            var underTest = new EventStore(_persistence);

            await underTest.Append("streamName", EventStore.StreamPositions.Any, new byte[0], new byte[0]);

            await underTest.Append("streamName2", EventStore.StreamPositions.Any, new byte[0], new byte[0]);

            await underTest.Append("streamName2", EventStore.StreamPositions.Any, new byte[0], new byte[0]);

            var events = underTest.ReadStreamForward("streamName", 0);
            var total  = await events.CountAsync();

            Assert.Equal(1, total);

            events = underTest.ReadStreamForward("streamName2", 0);
            total  = await events.CountAsync();

            Assert.Equal(2, total);
        }
        public async Task WriteEventWhenExpectedPositionIsAnyOnAppend()
        {
            var eventPersistence = _persistence;
            var underTest        = new EventStore(eventPersistence);
            var result           = await underTest.Append("streamName", EventStore.StreamPositions.Any, new byte[0], new byte[0]);

            Assert.Equal(0, result.NextPosition);

            var eventsTotal = await _persistence.GetAllEvents().CountAsync();

            Assert.Equal(1, eventsTotal);
        }
示例#10
0
        public void GivenSetOfEvents_WithFetchEventsFromDifferentVersionNumber_ThenProperSetsAreLoaded()
        {
            //Given
            var streamId = Guid.NewGuid();
            var taskId   = Guid.NewGuid();

            //When
            EventStore.Append(streamId, new TaskCreated {
                TaskId = taskId, Description = "Initial Name"
            });
            Session.SaveChanges();

            EventStore.Append(streamId, new TaskUpdated {
                TaskId = taskId, Description = "Updated name"
            });
            Session.SaveChanges();

            EventStore.Append(streamId, new TaskUpdated {
                TaskId = taskId, Description = "Updated again name"
            },
                              new TaskUpdated {
                TaskId = taskId, Description = "Updated again and again name"
            });
            Session.SaveChanges();

            //Then
            //version after create
            var events = EventStore.FetchStream(streamId, 1);

            events.Count.Should().Be.EqualTo(1);

            //version after first update
            events = EventStore.FetchStream(streamId, 2);
            events.Count.Should().Be.EqualTo(2);

            //even though 3 and 4 updates were append at the same time version is incremented for both of them
            events = EventStore.FetchStream(streamId, 3);
            events.Count.Should().Be.EqualTo(3);

            events = EventStore.FetchStream(streamId, 4);
            events.Count.Should().Be.EqualTo(4);

            //fetching with version equal to 0 returns the most recent state
            events = EventStore.FetchStream(streamId, 0);
            events.Count.Should().Be.EqualTo(4);

            //providing bigger version than current doesn't throws exception - returns most recent state
            events = EventStore.FetchStream(streamId, 100);
            events.Count.Should().Be.EqualTo(4);
        }
    public void GivenOneEvent_WhenEventsArePublishedWithStreamId_ThenEventsAreSavedWithoutErrorAndStreamIsStarted()
    {
        var @event   = new IssueCreated(Guid.NewGuid(), "Description");
        var streamId = Guid.NewGuid();

        EventStore.Append(streamId, @event);

        Session.SaveChanges();

        var streamState = EventStore.FetchStreamState(streamId);

        streamState.Should().Not.Be.Null();
        streamState.Version.Should().Be.EqualTo(1);
    }
示例#12
0
        public async Task OnGetAsync(int guest)
        {
            Bill = _events
                   .Project(
                default(BillViewModel),
                BillViewModel.OpenBillFor(guest)
                );
            var paymentMethods = await _billingClient.GetFromJsonAsync <PaymentMethod[]>($"payment/{Bill.Bill}");

            _events.Append(new PaymentMethodsSupported(guest, Bill.Bill, paymentMethods));

            SupportedPaymentMethods = paymentMethods
                                      .Select(x => new SelectListItem {
                Text = x.ToString(), Value = x.ToString()
            })
                                      .ToList();

            Command = new PaymentCommand
            {
                Guest = guest,
                Bill  = Bill.Bill
            };
        }
示例#13
0
        public void GivenExistingStreamWithOneEvent_WhenEventIsAppended_ThenItLoadsTwoEvents()
        {
            //Given
            var streamId = GetExistingStreamId();

            //When
            EventStore.Append(streamId, new IssueUpdated(issueId, "New Description"));
            Session.SaveChanges();

            //Then
            var events = EventStore.FetchStream(streamId);

            events.Count.Should().Be.EqualTo(2);
            events.Last().Version.Should().Be.EqualTo(2);
        }
示例#14
0
        public void GivenSetOfEvents_WithFetchEventsFromDifferentTimes_ThenProperSetsAreLoaded()
        {
            //Given
            var streamId = Guid.NewGuid();
            var taskId   = Guid.NewGuid();

            //When
            var beforeCreateTimestamp = DateTime.UtcNow;

            EventStore.Append(streamId, new TaskCreated {
                TaskId = taskId, Description = "Initial Name"
            });
            Session.SaveChanges();
            var createTimestamp = DateTime.UtcNow;

            EventStore.Append(streamId, new TaskUpdated {
                TaskId = taskId, Description = "Updated name"
            });
            Session.SaveChanges();
            var firstUpdateTimestamp = DateTime.UtcNow;

            EventStore.Append(streamId, new TaskUpdated {
                TaskId = taskId, Description = "Updated again name"
            },
                              new TaskUpdated {
                TaskId = taskId, Description = "Updated again and again name"
            });
            Session.SaveChanges();
            var secondUpdateTimestamp = DateTime.UtcNow;

            //Then
            var events = EventStore.FetchStream(streamId, timestamp: beforeCreateTimestamp);

            events.Count.Should().Be.EqualTo(0);

            events = EventStore.FetchStream(streamId, timestamp: createTimestamp);
            events.Count.Should().Be.EqualTo(1);

            events = EventStore.FetchStream(streamId, timestamp: firstUpdateTimestamp);
            events.Count.Should().Be.EqualTo(2);

            events = EventStore.FetchStream(streamId, timestamp: secondUpdateTimestamp);
            events.Count.Should().Be.EqualTo(4);
        }
        public ComponentRegistrarBuilder RegisterEventsStorage <TAppendOnlyStore>(string connectionName = "EventStore")
            where TAppendOnlyStore : class, IAppendOnlyStore
        {
            if (!string.IsNullOrWhiteSpace(connectionName))
            {
                var connectionString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;

                _container.Register(
                    Component.For <IAppendOnlyStore>()
                    .ImplementedBy(typeof(TAppendOnlyStore))
                    .Named(typeof(TAppendOnlyStore).Name)
                    .DependsOn(
                        Property.ForKey("connectionString")
                        .Eq(connectionString ?? typeof(TAppendOnlyStore).Name)).IsDefault()
                    .LifeStyle.Transient);
                _container.Register(
                    Component.For(typeof(IEventStore))
                    .ImplementedBy(typeof(EventStore))
                    .Named("eventStore").LifestyleTransient());
            }
            else
            {
                _container.Register(
                    Component.For <IAppendOnlyStore>()
                    .ImplementedBy(typeof(TAppendOnlyStore))
                    .Named(typeof(TAppendOnlyStore).Name)
                    .LifeStyle.Singleton);
                _container.Register(
                    Component.For(typeof(IEventStore))
                    .ImplementedBy(typeof(EventStore))
                    .Named("eventStore").LifestyleTransient());
            }


            EventStore = _container.Resolve <IEventStore>();

            DomainEventPublisher.Instance.Subscribe(domainEvent => EventStore.Append(domainEvent));

            return(this);
        }