using GamificationService.Database.GenericRepository; using GamificationService.Models.Database; using Microsoft.EntityFrameworkCore.Storage; namespace GamificationService.Database.UnitOfWork; public class UnitOfWork : IUnitOfWork { #region Fields private readonly ApplicationContext _context; private IDbContextTransaction? _transaction; // Repository fields private IGenericRepository? _rankRepository; private IGenericRepository? _skillRepository; private IGenericRepository? _playerRepository; private IGenericRepository? _missionCategoryRepository; private IGenericRepository? _missionRepository; private IGenericRepository? _missionRankRuleRepository; private IGenericRepository? _missionSkillRewardRepository; private IGenericRepository? _missionItemRewardRepository; private IGenericRepository? _rankMissionRuleRepository; private IGenericRepository? _rankSkillRuleRepository; private IGenericRepository? _playerSkillRepository; private IGenericRepository? _playerMissionRepository; private IGenericRepository? _dialogueRepository; private IGenericRepository? _dialogueMessageRepository; private IGenericRepository? _dialogueMessageResponseOptionRepository; #endregion public UnitOfWork(ApplicationContext context) { _context = context; } #region Repositories public IGenericRepository Ranks => _rankRepository ??= new GenericRepository(_context); public IGenericRepository Skills => _skillRepository ??= new GenericRepository(_context); public IGenericRepository Players => _playerRepository ??= new GenericRepository(_context); public IGenericRepository MissionCategories => _missionCategoryRepository ??= new GenericRepository(_context); public IGenericRepository Missions => _missionRepository ??= new GenericRepository(_context); public IGenericRepository MissionRankRules => _missionRankRuleRepository ??= new GenericRepository(_context); public IGenericRepository MissionSkillRewards => _missionSkillRewardRepository ??= new GenericRepository(_context); public IGenericRepository MissionItemRewards => _missionItemRewardRepository ??= new GenericRepository(_context); public IGenericRepository RankMissionRules => _rankMissionRuleRepository ??= new GenericRepository(_context); public IGenericRepository RankSkillRules => _rankSkillRuleRepository ??= new GenericRepository(_context); public IGenericRepository PlayerSkills => _playerSkillRepository ??= new GenericRepository(_context); public IGenericRepository PlayerMissions => _playerMissionRepository ??= new GenericRepository(_context); public IGenericRepository Dialogues => _dialogueRepository ??= new GenericRepository(_context); public IGenericRepository DialogueMessages => _dialogueMessageRepository ??= new GenericRepository(_context); public IGenericRepository DialogueMessageResponseOptions => _dialogueMessageResponseOptionRepository ??= new GenericRepository(_context); #endregion #region Save Methods public bool SaveChanges() => _context.SaveChanges() > 0; public async Task SaveChangesAsync() => (await _context.SaveChangesAsync()) > 0; #endregion #region Transactions public async Task BeginTransactionAsync() { if (_transaction is not null) throw new InvalidOperationException("A transaction has already been started."); _transaction = await _context.Database.BeginTransactionAsync(); } public async Task CommitTransactionAsync() { if (_transaction is null) throw new InvalidOperationException("No transactions have been started yet."); try { await _transaction.CommitAsync(); } catch { await RollbackTransactionAsync(); throw; } finally { await _transaction.DisposeAsync(); _transaction = null; } } public async Task RollbackTransactionAsync() { if (_transaction is null) return; await _transaction.RollbackAsync(); await _transaction.DisposeAsync(); _transaction = null; } #endregion }