/// <summary> /// Encapsulates several repository calls with one DbContext. Any exceptions thrown inside will end up rolling back all repository transactions. /// /// To change a repository's context to use unitOfWork's localContext, make sure to call /// <c>rRegistrar.ConvertContextOfRepository(myRepo).ToUse(localContext);</c> /// </summary> /// /// <param name="repoWork">Asynchronous lambda to do the repository transactions</param> public async Task Run(RepoWork repoWork) { RepositoryRegistry rRegistry = new RepositoryRegistry(); RepositoryRegistryRegistrar rRegistrar = new RepositoryRegistryRegistrar(rRegistry); CintaUangDbContext localContext = null; try { using (var scope = serviceProvider.CreateScope()) { localContext = scope.ServiceProvider.GetService <CintaUangDbContext>(); localContext.Database.BeginTransaction(); await repoWork(rRegistrar, localContext); localContext.Database.CommitTransaction(); } } catch (Exception e) { localContext.Database.RollbackTransaction(); throw e; } finally { /** * Convert All DbContexts of all repositories registered in registry */ rRegistry.GetRepositories().ForEach(unitOfWorkRepository => unitOfWorkRepository.RevertToPreviousDbContext()); } }
/// <summary> /// Encapsulates several repository calls with one DbContext. Any exceptions thrown inside will end up rolling back all repository transactions. /// /// To change a repository's context to use unitOfWork's localContext, make sure to call /// <c>rRegistrar.ConvertContextOfRepository(myRepo).ToUse(localContext);</c> /// </summary> /// /// <param name="repoWork">Asynchronous lambda to do the repository transactions</param> public async Task RunAsync(RepoWorkAsync repoWork) { RepositoryRegistry rRegistry = new RepositoryRegistry(); RepositoryRegistryRegistrar rRegistrar = new RepositoryRegistryRegistrar(rRegistry); ConcertoDbContext localContext = null; try { using (var scope = serviceProvider.CreateScope()) { localContext = scope.ServiceProvider.GetService <ConcertoDbContext>(); localContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; using (var trans = localContext.Database.BeginTransaction()) { try { await repoWork(rRegistrar, localContext); trans.Commit(); } catch (Exception e) { trans.Rollback(); throw e; } } } } catch (Exception e) { throw e; } finally { /** * Convert All DbContexts of all repositories registered in registry */ rRegistry.GetRepositories().ForEach(unitOfWorkRepository => unitOfWorkRepository.RevertToPreviousDbContext()); rRegistry.Clear(); } }