11using System ;
22using System . Threading ;
33using System . Threading . Tasks ;
4+ using System . Transactions ;
5+ using Dotnet6 . GraphQL4 . CrossCutting . Notifications ;
6+ using Dotnet6 . GraphQL4 . Repositories . Abstractions . DependencyInjection ;
7+ using Dotnet6 . GraphQL4 . Repositories . Abstractions . Transactions . Extensions ;
48using Microsoft . EntityFrameworkCore ;
59using Microsoft . EntityFrameworkCore . Infrastructure ;
610using Microsoft . EntityFrameworkCore . Storage ;
11+ using Microsoft . Extensions . Options ;
712
813namespace Dotnet6 . GraphQL4 . Repositories . Abstractions . UnitsOfWork
914{
1015 public class UnitOfWork : IUnitOfWork
1116 {
1217 private readonly DatabaseFacade _database ;
1318 private readonly DbContext _dbContext ;
19+ private readonly IOptionsMonitor < ApplicationTransactionOptions > _options ;
20+ private readonly INotificationContext _notificationContext ;
1421
15- public UnitOfWork ( DbContext dbContext )
22+ public UnitOfWork ( DbContext dbContext , IOptionsMonitor < ApplicationTransactionOptions > options , INotificationContext notificationContext )
1623 {
1724 _dbContext = dbContext ;
25+ _options = options ;
1826 _database = _dbContext . Database ;
27+ _notificationContext = notificationContext ;
1928 }
2029
21- public IDbContextTransaction BeginTransaction ( )
22- => _database . BeginTransaction ( ) ;
23-
24- public Task < IDbContextTransaction > BeginTransactionAsync ( CancellationToken cancellationToken )
25- => _database . BeginTransactionAsync ( cancellationToken ) ;
30+ public TResult ExecuteInTransaction < TResult > ( Func < TResult > operation , Func < bool > condition )
31+ => CreateExecutionStrategy ( ) . Execute ( ( ) => ExecuteWithScope ( operation , condition ) ) ;
32+
33+ public Task < TResult > ExecuteInTransactionAsync < TResult > ( Func < CancellationToken , Task < TResult > > operationAsync , Func < CancellationToken , Task < bool > > condition , CancellationToken cancellationToken )
34+ => CreateExecutionStrategy ( ) . ExecuteAsync ( ct => ExecuteWithScopeAsync ( operationAsync , condition , ct ) , cancellationToken ) ;
35+
36+ private Task < TResult > ExecuteWithScopeAsync < TResult > ( Func < CancellationToken , Task < TResult > > operationAsync , Func < CancellationToken , Task < bool > > condition , CancellationToken cancellationToken )
37+ => operationAsync
38+ . TransactionAsync ( )
39+ . WithScopeOption ( TransactionScopeOption . Required )
40+ . WithOptions ( options => options . IsolationLevel = _options . CurrentValue . IsolationLevel )
41+ . WithScopeAsyncFlowOption ( TransactionScopeAsyncFlowOption . Enabled )
42+ . WithConditionAsync ( condition ?? ( _ => _notificationContext . AllValidAsync ) )
43+ . ExecuteAsync ( cancellationToken ) ;
44+
45+ private TResult ExecuteWithScope < TResult > ( Func < TResult > operation , Func < bool > condition )
46+ => operation
47+ . Transaction ( )
48+ . WithScopeOption ( TransactionScopeOption . Required )
49+ . WithOptions ( options => options . IsolationLevel = _options . CurrentValue . IsolationLevel )
50+ . WithScopeAsyncFlowOption ( TransactionScopeAsyncFlowOption . Enabled )
51+ . WithCondition ( condition ?? ( ( ) => _notificationContext . AllValid ) )
52+ . Execute ( ) ;
53+
54+ private IExecutionStrategy CreateExecutionStrategy ( )
55+ => _database . CreateExecutionStrategy ( ) ;
2656
2757 public bool SaveChanges ( )
2858 => _dbContext . SaveChanges ( true ) > default ( int ) ;
2959
3060 public async Task < bool > SaveChangesAsync ( CancellationToken cancellationToken )
3161 => await _dbContext . SaveChangesAsync ( true , cancellationToken ) > default ( int ) ;
32-
33- public void CommitTransaction ( )
34- => _database . CommitTransaction ( ) ;
35-
36- public Task CommitTransactionAsync ( CancellationToken cancellationToken )
37- => _database . CommitTransactionAsync ( cancellationToken ) ;
38-
39- public void RollbackTransaction ( )
40- => _database . RollbackTransaction ( ) ;
41-
42- public Task RollbackTransactionAsync ( CancellationToken cancellationToken )
43- => _database . RollbackTransactionAsync ( cancellationToken ) ;
44-
45- public void Dispose ( )
46- {
47- _dbContext ? . Dispose ( ) ;
48- GC . SuppressFinalize ( this ) ;
49- }
5062 }
5163}
0 commit comments