public void ResolvedEventHandlersAreExecutedInCorrectOrder()
        {
            TestAggregateRoot aggregateRoot = new TestAggregateRoot(Guid.NewGuid());

            aggregateRoot.ApplyEvent(domainEvent1);

            TestAggregateRoot2 aggregateRoot2 = new TestAggregateRoot2(Guid.NewGuid());

            aggregateRoot.ApplyEvent(domainEvent2);

            sut.ApplyChanges(aggregateRoot, aggregateRoot2);

            Received.InOrder(() =>
            {
                unitOfWorkDomainEventHandler1.Execute(domainEvent1, unitOfWork);
                unitOfWorkDomainEventHandler2.Execute(domainEvent1, unitOfWork);
                unitOfWorkDomainEventHandler1.Execute(domainEvent2, unitOfWork);
                unitOfWorkDomainEventHandler2.Execute(domainEvent2, unitOfWork);
                unitOfWork.SaveChanges();
                domainEventHandler3.Execute(domainEvent1);
                domainEventHandler4.Execute(domainEvent1);
                domainEventHandler3.Execute(domainEvent2);
                domainEventHandler4.Execute(domainEvent2);
            });
        }
        public void ChangesInUnitOfWorkAreSavedOnce()
        {
            TestAggregateRoot aggregateRoot = new TestAggregateRoot(Guid.NewGuid());

            aggregateRoot.ApplyEvent(domainEvent1);

            TestAggregateRoot2 aggregateRoot2 = new TestAggregateRoot2(Guid.NewGuid());

            aggregateRoot.ApplyEvent(domainEvent2);

            sut.ApplyChanges(aggregateRoot, aggregateRoot2);

            unitOfWork.Received(1).SaveChanges();
        }
        public void InaccessibleTypeParametersCanBeUsed()
        {
            // This test is necessary for checking that the repository can be used with inaccessible type parameters.
            // See the bug in .NET Framework: https://connect.microsoft.com/VisualStudio/feedback/details/672411/bug-in-dynamic-dispatch-when-using-generic-type-parameters

            IUnitOfWorkDomainEventHandler <TestDomainEvent, InternalUnitOfWork> domainEventHandler =
                Substitute.For <IUnitOfWorkDomainEventHandler <TestDomainEvent, InternalUnitOfWork> >();
            IEnumerable <IUnitOfWorkDomainEventHandler <TestDomainEvent, InternalUnitOfWork> > eventHandlers = new List
                                                                                                               <IUnitOfWorkDomainEventHandler <TestDomainEvent, InternalUnitOfWork> >
            {
                domainEventHandler
            };

            unitOfWorkEventHandlerResolver.ResolveEventHandlers <IUnitOfWorkDomainEventHandler <TestDomainEvent, InternalUnitOfWork> >().Returns(eventHandlers);
            unitOfWorkEventHandlerResolver.ResolveEventHandlers <IUnitOfWorkDomainEventHandler <TestDomainEvent, InternalUnitOfWork> >().Returns(eventHandlers);

            InternalAggregateRoot aggregateRoot = new InternalAggregateRoot(Guid.NewGuid());

            aggregateRoot.ApplyEvent(domainEvent1);

            TestAggregateRoot2 aggregateRoot2 = new TestAggregateRoot2(Guid.NewGuid());

            aggregateRoot.ApplyEvent(domainEvent2);

            InternalUnitOfWork internalUnitOfWork = new InternalUnitOfWork();

            var privateSut = new InternalCompositeRepository(eventHandlerResolver, unitOfWorkEventHandlerResolver, internalUnitOfWork);

            privateSut.ApplyChanges(aggregateRoot, aggregateRoot2);

            Received.InOrder(() =>
            {
                domainEventHandler.Execute(domainEvent1, internalUnitOfWork);
                domainEventHandler.Execute(domainEvent2, internalUnitOfWork);
                internalUnitOfWork.SaveChanges();
            });
        }
        public void OnlyUnitOfWorkEventsAreHandledIfCommitFails()
        {
            TestAggregateRoot aggregateRoot = new TestAggregateRoot(Guid.NewGuid());

            aggregateRoot.ApplyEvent(domainEvent1);

            TestAggregateRoot2 aggregateRoot2 = new TestAggregateRoot2(Guid.NewGuid());

            aggregateRoot.ApplyEvent(domainEvent2);

            unitOfWork
            .When(u => u.SaveChanges())
            .Do(callInfo => { throw new OperationCanceledException(); });

            bool exceptionCatched = false;

            try
            {
                sut.ApplyChanges(aggregateRoot, aggregateRoot2);
            }
            catch (OperationCanceledException)
            {
                exceptionCatched = true;
            }

            Assert.IsTrue(exceptionCatched);
            unitOfWorkDomainEventHandler1.Received().Execute(domainEvent1, unitOfWork);
            unitOfWorkDomainEventHandler2.Received().Execute(domainEvent1, unitOfWork);
            unitOfWorkDomainEventHandler1.Received().Execute(domainEvent2, unitOfWork);
            unitOfWorkDomainEventHandler2.Received().Execute(domainEvent2, unitOfWork);
            unitOfWork.Received().SaveChanges();
            domainEventHandler3.DidNotReceive().Execute(domainEvent1);
            domainEventHandler4.DidNotReceive().Execute(domainEvent1);
            domainEventHandler3.DidNotReceive().Execute(domainEvent2);
            domainEventHandler4.DidNotReceive().Execute(domainEvent2);
        }
        public void AggregateRootOfSecondSpecifiedTypeIsFound()
        {
            TestAggregateRoot2 aggregateRoot = sut.Find <TestAggregateRoot2>(Guid.NewGuid());

            Assert.IsNotNull(aggregateRoot);
        }