コード例 #1
0
        public async Task CommitAsync_WithoutCancellationTokenInNestedUow_SavedChangesInParentUow()
        {
            var dbContext = new Mock <DbContext>();
            Func <DbContext> dbContextFactory = () => dbContext.Object;


            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();

            var unitOfWorkProvider = new EntityFrameworkUnitOfWorkProvider(unitOfWorkRegistryStub, dbContextFactory);

            using (var uow = unitOfWorkProvider.Create())
            {
                using (var nested = unitOfWorkProvider.Create())
                {
                    await nested.CommitAsync();

                    // verify, that method has NEVER been called
                    dbContext.Verify(x => x.SaveChangesAsync(It.IsAny <CancellationToken>()), Times.Never);
                }

                await uow.CommitAsync();

                // verify, that method has been called ONCE
                dbContext.Verify(x => x.SaveChangesAsync(It.IsAny <CancellationToken>()), Times.Once);
            }
        }
コード例 #2
0
        public void Commit_CorrectChildRequestIgnoredBehavior()
        {
            Func <DbContext> dbContextFactory = () => new Mock <DbContext>().Object;

            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();

            var unitOfWorkProvider = new EntityFrameworkUnitOfWorkProvider(unitOfWorkRegistryStub, dbContextFactory);

            Assert.Throws <ChildCommitPendingException>(() =>
            {
                using (unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                {
                    using (var unitOfWorkChild = unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                    {
                        unitOfWorkChild.Commit();
                    }
                }
            });

            // test that unit of work provider keeps working after caught exception
            using (unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
            {
                using (unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                {
                }
            }
        }
コード例 #3
0
        public async Task Commit_Transaction_CallRollback_UserCatch()
        {
            var dbContextFactory = GetContextFactory();

            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();

            var unitOfWorkProvider = new EntityFrameworkUnitOfWorkProvider <InMemoryDbContext>(unitOfWorkRegistryStub, dbContextFactory);

            var scopeMock = new Mock <UnitOfWorkTransactionScope <InMemoryDbContext> >(unitOfWorkProvider);
            var scope     = scopeMock.Object;

            await scope.ExecuteAsync(async uowParent =>
            {
                Assert.True(uowParent.IsInTransaction);

                await uowParent.CommitAsync();

                using (var uowChild = (EntityFrameworkUnitOfWork <InMemoryDbContext>)unitOfWorkProvider.Create())
                {
                    await uowChild.CommitAsync();

                    try
                    {
                        uowParent.RollbackTransaction();
                    }
                    catch (Exception)
                    {
                        // user catches any exceptions
                    }
                }
            });

            scopeMock.Protected().Verify("AfterRollback", Times.Once());
        }
コード例 #4
0
        public async Task Commit_Transaction_CallRollback_OnException()
        {
            var dbContextFactory = GetContextFactory();

            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();

            var unitOfWorkProvider = new EntityFrameworkUnitOfWorkProvider <InMemoryDbContext>(unitOfWorkRegistryStub, dbContextFactory);

            var scope = unitOfWorkProvider.CreateTransactionScope();

            var exceptionKey = Guid.NewGuid().ToString();

            try
            {
                await scope.ExecuteAsync(async uowParent =>
                {
                    Assert.True(uowParent.IsInTransaction);

                    await uowParent.CommitAsync();

                    throw new Exception(exceptionKey);
                });
            }
            catch (Exception e) when(e.Message == exceptionKey)
            {
                // test exception caught, passed
            }
        }
コード例 #5
0
        public async Task Commit_UOWHasChild_CallCommitCore()
        {
            Func <DbContext> dbContextFactory = () => new Mock <DbContext>().Object;

            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();

            var unitOfWorkProvider = new EntityFrameworkUnitOfWorkProvider(unitOfWorkRegistryStub, dbContextFactory);

            var unitOfWorkParentMock = new Mock <EntityFrameworkUnitOfWork>(unitOfWorkProvider, dbContextFactory, DbContextOptions.ReuseParentContext)
            {
                CallBase = true
            };

            using (var unitOfWorkParent = unitOfWorkParentMock.Object)
            {
                unitOfWorkRegistryStub.RegisterUnitOfWork(unitOfWorkParent);

                using (var unitOfWorkChild = new EntityFrameworkUnitOfWork(unitOfWorkProvider, dbContextFactory, DbContextOptions.ReuseParentContext))
                {
                    await unitOfWorkChild.CommitAsync();
                }

                await unitOfWorkParent.CommitAsync();
            }
            unitOfWorkParentMock.Protected().Verify("CommitAsyncCore", Times.Once(), new CancellationToken());
        }
コード例 #6
0
        public void Commit_CallCommitCoreOnlyIfHasOwnDbContext()
        {
            Func <DbContext> dbContextFactory = () => new Mock <DbContext>().Object;

            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();

            var unitOfWorkProvider = new EntityFrameworkUnitOfWorkProvider(unitOfWorkRegistryStub, dbContextFactory);

            var unitOfWorkParentMock = new Mock <EntityFrameworkUnitOfWork>(unitOfWorkProvider, dbContextFactory, DbContextOptions.ReuseParentContext)
            {
                CallBase = true
            };

            using (var unitOfWorkParent = unitOfWorkParentMock.Object)
            {
                unitOfWorkRegistryStub.RegisterUnitOfWork(unitOfWorkParent);

                var unitOfWorkChildMock = new Mock <EntityFrameworkUnitOfWork>(unitOfWorkProvider, dbContextFactory, DbContextOptions.ReuseParentContext)
                {
                    CallBase = true
                };
                using (var unitOfWorkChild = unitOfWorkChildMock.Object)
                {
                    unitOfWorkChild.Commit();
                }
                unitOfWorkChildMock.Protected().Verify("CommitCore", Times.Never());

                unitOfWorkParent.Commit();
            }
            unitOfWorkParentMock.Protected().Verify("CommitCore", Times.Once());
        }
コード例 #7
0
        public async Task CommitAsync_ThrowIfChildCommitRequestedNotFulfilledByRoot()
        {
            Func <DbContext> dbContextFactory = () => new Mock <DbContext>().Object;

            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();

            var unitOfWorkProvider = new EntityFrameworkUnitOfWorkProvider(unitOfWorkRegistryStub, dbContextFactory);

            await Assert.ThrowsAsync <ChildCommitPendingException>(async() =>
            {
                using (unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                {
                    using (var unitOfWorkChild = unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                    {
                        await unitOfWorkChild.CommitAsync();
                    }
                }
            });

            // test that unit of work provider keeps working after caught exception
            using (unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
            {
                using (unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                {
                }
            }
        }
コード例 #8
0
        public void TryGetDbContext_UnitOfWorkRegistryHasNotUnitOfWork_ReturnsNull()
        {
            var dbContext = new Mock <DbContext>().Object;
            Func <DbContext> dbContextFactory = () => dbContext;
            var unitOfWorkRegistryStub        = new ThreadLocalUnitOfWorkRegistry();
            var unitOfWorkProvider            = new EntityFrameworkUnitOfWorkProvider(unitOfWorkRegistryStub, dbContextFactory);

            var value = EntityFrameworkUnitOfWork.TryGetDbContext(unitOfWorkProvider);

            Assert.Null(value);
        }
コード例 #9
0
        private EntityFrameworkRepository <TEntity, int> CreateEntityFrameworkRepository <TEntity>() where TEntity : class, IEntity <int>, new()
        {
            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();
            var unitOfWorkProvider     = new EntityFrameworkUnitOfWorkProvider(unitOfWorkRegistryStub,
                                                                               CreateYesMinisterDbContext);
            IDateTimeProvider dateTimeProvider = new UtcDateTimeProvider();

            var unitOfWork = new EntityFrameworkUnitOfWork(unitOfWorkProvider, CreateYesMinisterDbContext,
                                                           DbContextOptions.ReuseParentContext);

            unitOfWorkRegistryStub.RegisterUnitOfWork(unitOfWork);

            return(new EntityFrameworkRepository <TEntity, int>(unitOfWorkProvider, dateTimeProvider));
        }
コード例 #10
0
        public void TryGetDbContext_UnitOfWorkRegistryHasUnitOfWork_ReturnCorrectDbContext()
        {
            var dbContext = new Mock <DbContext>().Object;
            Func <DbContext> dbContextFactory = () => dbContext;
            var unitOfWorkRegistryStub        = new ThreadLocalUnitOfWorkRegistry();
            var unitOfWorkProvider            = new EntityFrameworkUnitOfWorkProvider(unitOfWorkRegistryStub, dbContextFactory);
            var unitOfWork = new EntityFrameworkUnitOfWork(unitOfWorkProvider, dbContextFactory, DbContextOptions.ReuseParentContext);

            unitOfWorkRegistryStub.RegisterUnitOfWork(unitOfWork);

            var uowDbContext = EntityFrameworkUnitOfWork.TryGetDbContext(unitOfWorkProvider);

            Assert.NotNull(uowDbContext);
            Assert.Same(dbContext, uowDbContext);
        }
コード例 #11
0
        public void Commit_CorrectMultipleLayeredReuseParentBehavior()
        {
            Func <DbContext> dbContextFactory = () => new Mock <DbContext>().Object;

            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();

            var unitOfWorkProvider = new EntityFrameworkUnitOfWorkProvider(unitOfWorkRegistryStub, dbContextFactory);

            using (var unitOfWorkParent = unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
            {
                // 1st level, context 1
                using (unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                {
                    // 2nd level, context 1
                    using (unitOfWorkProvider.Create(DbContextOptions.AlwaysCreateOwnContext))
                    {
                        // 3rd level, context 2
                        using (unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                        {
                            // 4th level, context 2
                            using (var unitOfWorkParent3 = unitOfWorkProvider.Create(DbContextOptions.AlwaysCreateOwnContext))
                            {
                                // 5th level, context 3
                                using (unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                                {
                                    // 6th level, context 3
                                    using (unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                                    {
                                    }
                                    using (var unitOfWorkChild3 = unitOfWorkProvider.Create(DbContextOptions.ReuseParentContext))
                                    {
                                        // 7th level, context 3 commit requested
                                        unitOfWorkChild3.Commit();
                                    }
                                }
                                // commit mandatory, context 3 commit pending
                                unitOfWorkParent3.Commit();
                            }
                        }
                    }
                }
                // commit optional, no reusing child commit pending
                unitOfWorkParent.Commit();
            }
        }
コード例 #12
0
        public async Task Commit_Transaction_CallCommit_Nesting()
        {
            var dbContextFactory = GetContextFactory();

            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();

            var unitOfWorkProvider = new EntityFrameworkUnitOfWorkProvider <InMemoryDbContext>(unitOfWorkRegistryStub, dbContextFactory);

            var scopeMock = new Mock <UnitOfWorkTransactionScope <InMemoryDbContext> >(unitOfWorkProvider);
            var scope     = scopeMock.Object;

            await scope.ExecuteAsync(async uowParent =>
            {
                Assert.True(uowParent.IsInTransaction);

                await uowParent.CommitAsync();

                Assert.Equal(1, uowParent.CommitsCount);
                Assert.False(uowParent.CommitPending);

                using (var uowChild = (EntityFrameworkUnitOfWork <InMemoryDbContext>)unitOfWorkProvider.Create())
                {
                    await uowChild.CommitAsync();

                    Assert.Equal(1, uowChild.CommitsCount);
                    Assert.False(uowChild.CommitPending);

                    Assert.Equal(2, uowParent.CommitsCount);
                    Assert.False(uowParent.CommitPending);

                    using (var uowChildChild = (EntityFrameworkUnitOfWork <InMemoryDbContext>)unitOfWorkProvider.Create())
                    {
                        await uowChildChild.CommitAsync();
                    }

                    Assert.Equal(2, uowChild.CommitsCount);
                    Assert.False(uowChild.CommitPending);

                    Assert.Equal(3, uowParent.CommitsCount);
                    Assert.False(uowParent.CommitPending);
                }
            });

            scopeMock.Protected().Verify("AfterCommit", Times.Once());
        }
コード例 #13
0
        public void Commit_Transaction_CallCommit_Sync()
        {
            var dbContextFactory = GetContextFactory();

            var unitOfWorkRegistryStub = new ThreadLocalUnitOfWorkRegistry();

            var unitOfWorkProvider = new EntityFrameworkUnitOfWorkProvider <InMemoryDbContext>(unitOfWorkRegistryStub, dbContextFactory);

            var scopeMock = new Mock <UnitOfWorkTransactionScope <InMemoryDbContext> >(unitOfWorkProvider);
            var scope     = scopeMock.Object;

            scope.Execute(uowParent =>
            {
                Assert.True(uowParent.IsInTransaction);

                uowParent.Commit();

                Assert.Equal(1, uowParent.CommitsCount);
                Assert.False(uowParent.CommitPending);
            });

            scopeMock.Protected().Verify("AfterCommit", Times.Once());
        }
コード例 #14
0
        public void NestedDbContexts()
        {
            var registry = new ThreadLocalUnitOfWorkRegistry();
            var uowp1    = new EntityFrameworkUnitOfWorkProvider <CustomDbContext1>(registry, () => new CustomDbContext1());
            var uowp2    = new EntityFrameworkUnitOfWorkProvider <CustomDbContext2>(registry, () => new CustomDbContext2());

            using (var uow1 = uowp1.Create())
            {
                using (var uow2 = uowp2.Create())
                {
                    var current = registry.GetCurrent(0);
                    Assert.Equal(uow2, current);

                    var parent = registry.GetCurrent(1);
                    Assert.Equal(uow1, parent);

                    var inner = EntityFrameworkUnitOfWork.TryGetDbContext <CustomDbContext2>(uowp2);
                    Assert.Equal(((EntityFrameworkUnitOfWork <CustomDbContext2>)uow2).Context, inner);

                    var outer = EntityFrameworkUnitOfWork.TryGetDbContext <CustomDbContext1>(uowp1);
                    Assert.Equal(((EntityFrameworkUnitOfWork <CustomDbContext1>)uow1).Context, outer);
                }
            }
        }