public void UpdatingAnAggregateAfterPersistingMigrations()
        {
            var emptyMigrationsArray = new IEventMigration[0];
            IReadOnlyList <IEventMigration> migrations = emptyMigrationsArray;

            using (var container = CreateContainerForEventStoreType(() => migrations, EventStoreType))
            {
                var id = Guid.Parse("00000000-0000-0000-0000-000000000001");

                container.Resolve <DummyTimeSource>().UtcNow = DateTime.Parse("2001-01-01 12:00");

                var initialAggregate = TestAggregate.FromEvents(container.Resolve <IUtcTimeTimeSource>(), id, Seq.OfTypes <Ec1, E1>());
                var initialHistory   = initialAggregate.History;


                Func <IEventStoreSession> session    = () => container.Resolve <IEventStoreSession>();
                Func <IEventStore>        eventStore = () => container.Resolve <IEventStore>();

                container.ExecuteUnitOfWorkInIsolatedScope(() => session().Save(initialAggregate));

                migrations = Seq.Create(Replace <E1> .With <E5>()).ToList();

                container.ExecuteUnitOfWorkInIsolatedScope(() => eventStore().PersistMigrations());

                migrations = Seq.Create <IEventMigration>().ToList();

                container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get <TestAggregate>(id).RaiseEvents(new E2()));

                var aggregate = container.ExecuteInIsolatedScope(() => session().Get <TestAggregate>(id));

                var expected = TestAggregate.FromEvents(container.Resolve <IUtcTimeTimeSource>(), id, Seq.OfTypes <Ec1, E5, E2>()).History;
                AssertStreamsAreIdentical(expected: expected, migratedHistory: aggregate.History, descriptionOfHistory: "migrated history");

                var completeEventHistory = container.ExecuteInIsolatedScope(() => eventStore().ListAllEventsForTestingPurposesAbsolutelyNotUsableForARealEventStoreOfAnySize()).Cast <AggregateRootEvent>();
                AssertStreamsAreIdentical(expected: expected, migratedHistory: completeEventHistory, descriptionOfHistory: "streamed persisted history");

                Console.WriteLine($"Version");
                Console.WriteLine("Aggregate Effective Inserted Manual");
                Console.WriteLine("A E I M");
                completeEventHistory.ForEach(@event => Console.WriteLine($"{@event.AggregateRootVersion} {@event.EffectiveVersion} {@event.InsertedVersion} {@event.ManualVersion}"));

                ClearEventstoreCache(container);

                completeEventHistory = container.ExecuteInIsolatedScope(() => eventStore().ListAllEventsForTestingPurposesAbsolutelyNotUsableForARealEventStoreOfAnySize()).Cast <AggregateRootEvent>();
                AssertStreamsAreIdentical(expected: expected, migratedHistory: completeEventHistory, descriptionOfHistory: "streamed persisted history");
            }
        }
        public void UpdatingAnAggregateAfterPersistingMigrations()
        {
            var emptyMigrationsArray = new IEventMigration[0];
            IReadOnlyList<IEventMigration> migrations = emptyMigrationsArray;

            using(var container = CreateContainerForEventStoreType(() => migrations, EventStoreType))
            {

                var id = Guid.Parse("00000000-0000-0000-0000-000000000001");

                container.Resolve<DummyTimeSource>().UtcNow = DateTime.Parse("2001-01-01 12:00");

                var initialAggregate = TestAggregate.FromEvents(container.Resolve<IUtcTimeTimeSource>(), id, Seq.OfTypes<Ec1, E1>());
                var initialHistory = initialAggregate.History;


                Func<IEventStoreSession> session = () => container.Resolve<IEventStoreSession>();
                Func<IEventStore> eventStore = () => container.Resolve<IEventStore>();

                container.ExecuteUnitOfWorkInIsolatedScope(() => session().Save(initialAggregate));

                migrations = Seq.Create(Replace<E1>.With<E5>()).ToList();

                container.ExecuteUnitOfWorkInIsolatedScope(() => eventStore().PersistMigrations());

                migrations = Seq.Create<IEventMigration>().ToList();

                container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get<TestAggregate>(id).RaiseEvents(new E2()));

                var aggregate = container.ExecuteInIsolatedScope(() => session().Get<TestAggregate>(id));

                var expected = TestAggregate.FromEvents(container.Resolve<IUtcTimeTimeSource>(), id, Seq.OfTypes<Ec1, E5, E2>()).History;
                AssertStreamsAreIdentical(expected: expected, migratedHistory: aggregate.History, descriptionOfHistory: "migrated history");

                var completeEventHistory =container.ExecuteInIsolatedScope(() => eventStore().ListAllEventsForTestingPurposesAbsolutelyNotUsableForARealEventStoreOfAnySize()).Cast<AggregateRootEvent>();
                AssertStreamsAreIdentical(expected: expected, migratedHistory: completeEventHistory, descriptionOfHistory: "streamed persisted history");

                Console.WriteLine($"Version");
                Console.WriteLine("Aggregate Effective Inserted Manual");
                Console.WriteLine("A E I M");
                completeEventHistory.ForEach(@event => Console.WriteLine($"{@event.AggregateRootVersion} {@event.EffectiveVersion} {@event.InsertedVersion} {@event.ManualVersion}"));

                ClearEventstoreCache(container);

                completeEventHistory = container.ExecuteInIsolatedScope(() => eventStore().ListAllEventsForTestingPurposesAbsolutelyNotUsableForARealEventStoreOfAnySize()).Cast<AggregateRootEvent>();
                AssertStreamsAreIdentical(expected: expected, migratedHistory: completeEventHistory, descriptionOfHistory: "streamed persisted history");
            }
        }
        public void PersistingMigrationsOfTheSameAggregateMultipleTimesWithEventsAddedInTheMiddleAndAfter()
        {
            var emptyMigrationsArray = new IEventMigration[0];
            IReadOnlyList <IEventMigration> migrations = emptyMigrationsArray;

            using (var container = CreateContainerForEventStoreType(() => migrations, EventStoreType))
            {
                var id = Guid.Parse("00000000-0000-0000-0000-000000000001");

                container.Resolve <DummyTimeSource>().UtcNow = DateTime.Parse("2001-01-01 12:00");

                var aggregate      = TestAggregate.FromEvents(container.Resolve <IUtcTimeTimeSource>(), id, Seq.OfTypes <Ec1, E1, E2, E3, E4>());
                var initialHistory = aggregate.History;


                Func <IEventStoreSession> session    = () => container.Resolve <IEventStoreSession>();
                Func <IEventStore>        eventStore = () => container.Resolve <IEventStore>();

                var firstSavedHistory = container.ExecuteUnitOfWorkInIsolatedScope(
                    () =>
                {
                    session().Save(aggregate);
                    return(session().Get <TestAggregate>(id).History);
                });


                AssertStreamsAreIdentical(initialHistory, firstSavedHistory, "first saved history");

                migrations = Seq.Create(Replace <E1> .With <E5>()).ToList();

                var migratedHistory = container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get <TestAggregate>(id).History);
                var expectedAfterReplacingE1WithE5 =
                    TestAggregate.FromEvents(container.Resolve <IUtcTimeTimeSource>(), id, Seq.OfTypes <Ec1, E5, E2, E3, E4>()).History;
                AssertStreamsAreIdentical(expected: expectedAfterReplacingE1WithE5, migratedHistory: migratedHistory, descriptionOfHistory: "migrated history");

                var historyAfterPersistingButBeforeReload = container.ExecuteUnitOfWorkInIsolatedScope(
                    () =>
                {
                    eventStore().PersistMigrations();
                    return(session().Get <TestAggregate>(id).History);
                });

                AssertStreamsAreIdentical(expected: expectedAfterReplacingE1WithE5, migratedHistory: historyAfterPersistingButBeforeReload, descriptionOfHistory: "migrated, persisted");

                var historyAfterPersistingAndReloading = container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get <TestAggregate>(id).History);
                AssertStreamsAreIdentical(expected: expectedAfterReplacingE1WithE5, migratedHistory: historyAfterPersistingAndReloading, descriptionOfHistory: "migrated, persisted, reloaded");

                container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get <TestAggregate>(id).RaiseEvents(new E6(), new E7()));

                migrations = Seq.Create(Replace <E2> .With <E6>()).ToList();
                ClearEventstoreCache(container);

                migratedHistory = container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get <TestAggregate>(id).History);
                var expectedAfterReplacingE2WithE6 = TestAggregate.FromEvents(container.Resolve <IUtcTimeTimeSource>(), id, Seq.OfTypes <Ec1, E5, E6, E3, E4, E6, E7>()).History;
                AssertStreamsAreIdentical(expected: expectedAfterReplacingE2WithE6, migratedHistory: migratedHistory, descriptionOfHistory: "migrated history");

                historyAfterPersistingButBeforeReload = container.ExecuteUnitOfWorkInIsolatedScope(
                    () =>
                {
                    eventStore().PersistMigrations();
                    return(session().Get <TestAggregate>(id).History);
                });

                AssertStreamsAreIdentical(expected: expectedAfterReplacingE2WithE6, migratedHistory: historyAfterPersistingButBeforeReload, descriptionOfHistory: "migrated, persisted");
                historyAfterPersistingAndReloading = container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get <TestAggregate>(id).History);
                AssertStreamsAreIdentical(expected: expectedAfterReplacingE2WithE6, migratedHistory: historyAfterPersistingAndReloading, descriptionOfHistory: "migrated, persisted, reloaded");

                migrations = Seq.Empty <IEventMigration>().ToList();
                container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get <TestAggregate>(id).RaiseEvents(new E8(), new E9()));
                historyAfterPersistingAndReloading = container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get <TestAggregate>(id).History);
                var expectedAfterReplacingE2WithE6AndRaisingE8E9 = TestAggregate.FromEvents(container.Resolve <IUtcTimeTimeSource>(), id, Seq.OfTypes <Ec1, E5, E6, E3, E4, E6, E7, E8, E9>()).History;
                AssertStreamsAreIdentical(expected: expectedAfterReplacingE2WithE6AndRaisingE8E9, migratedHistory: historyAfterPersistingAndReloading, descriptionOfHistory: "migrated, persisted, reloaded");
            }
        }
        public void PersistingMigrationsOfTheSameAggregateMultipleTimesWithEventsAddedInTheMiddleAndAfter()
        {
            var emptyMigrationsArray = new IEventMigration[0];
            IReadOnlyList<IEventMigration> migrations = emptyMigrationsArray;

            using (var container = CreateContainerForEventStoreType(() => migrations, EventStoreType))
            {

                var id = Guid.Parse("00000000-0000-0000-0000-000000000001");

                container.Resolve<DummyTimeSource>().UtcNow = DateTime.Parse("2001-01-01 12:00");

                var aggregate = TestAggregate.FromEvents(container.Resolve<IUtcTimeTimeSource>(), id, Seq.OfTypes<Ec1, E1, E2, E3, E4>());
                var initialHistory = aggregate.History;


                Func<IEventStoreSession> session = () => container.Resolve<IEventStoreSession>();
                Func<IEventStore> eventStore = () => container.Resolve<IEventStore>();

                var firstSavedHistory = container.ExecuteUnitOfWorkInIsolatedScope(
                    () =>
                    {
                        session().Save(aggregate);
                        return session().Get<TestAggregate>(id).History;
                    });


                AssertStreamsAreIdentical(initialHistory, firstSavedHistory, "first saved history");

                migrations = Seq.Create(Replace<E1>.With<E5>()).ToList();

                var migratedHistory = container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get<TestAggregate>(id).History);
                var expectedAfterReplacingE1WithE5 =
                    TestAggregate.FromEvents(container.Resolve<IUtcTimeTimeSource>(), id, Seq.OfTypes<Ec1, E5, E2, E3, E4>()).History;
                AssertStreamsAreIdentical(expected: expectedAfterReplacingE1WithE5, migratedHistory: migratedHistory, descriptionOfHistory: "migrated history");

                var historyAfterPersistingButBeforeReload = container.ExecuteUnitOfWorkInIsolatedScope(
                    () =>
                    {
                        eventStore().PersistMigrations();
                        return session().Get<TestAggregate>(id).History;
                    });

                AssertStreamsAreIdentical(expected: expectedAfterReplacingE1WithE5, migratedHistory: historyAfterPersistingButBeforeReload, descriptionOfHistory: "migrated, persisted");

                var historyAfterPersistingAndReloading = container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get<TestAggregate>(id).History);
                AssertStreamsAreIdentical(expected: expectedAfterReplacingE1WithE5, migratedHistory: historyAfterPersistingAndReloading, descriptionOfHistory: "migrated, persisted, reloaded");

                container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get<TestAggregate>(id).RaiseEvents(new E6(), new E7()));

                migrations = Seq.Create(Replace<E2>.With<E6>()).ToList();
                ClearEventstoreCache(container);

                migratedHistory = container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get<TestAggregate>(id).History);
                var expectedAfterReplacingE2WithE6 = TestAggregate.FromEvents(container.Resolve<IUtcTimeTimeSource>(), id, Seq.OfTypes<Ec1, E5, E6, E3, E4, E6, E7>()).History;
                AssertStreamsAreIdentical(expected: expectedAfterReplacingE2WithE6, migratedHistory: migratedHistory, descriptionOfHistory: "migrated history");

                historyAfterPersistingButBeforeReload = container.ExecuteUnitOfWorkInIsolatedScope(
                    () =>
                    {
                        eventStore().PersistMigrations();
                        return session().Get<TestAggregate>(id).History;
                    });

                AssertStreamsAreIdentical(expected: expectedAfterReplacingE2WithE6, migratedHistory: historyAfterPersistingButBeforeReload, descriptionOfHistory: "migrated, persisted");
                historyAfterPersistingAndReloading = container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get<TestAggregate>(id).History);
                AssertStreamsAreIdentical(expected: expectedAfterReplacingE2WithE6, migratedHistory: historyAfterPersistingAndReloading, descriptionOfHistory: "migrated, persisted, reloaded");

                migrations = Seq.Empty<IEventMigration>().ToList();
                container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get<TestAggregate>(id).RaiseEvents(new E8(), new E9()));
                historyAfterPersistingAndReloading = container.ExecuteUnitOfWorkInIsolatedScope(() => session().Get<TestAggregate>(id).History);
                var expectedAfterReplacingE2WithE6AndRaisingE8E9 = TestAggregate.FromEvents(container.Resolve<IUtcTimeTimeSource>(), id, Seq.OfTypes<Ec1, E5, E6, E3, E4, E6, E7, E8, E9>()).History;
                AssertStreamsAreIdentical(expected: expectedAfterReplacingE2WithE6AndRaisingE8E9, migratedHistory: historyAfterPersistingAndReloading, descriptionOfHistory: "migrated, persisted, reloaded");

            }

        }