using System.Collections.Concurrent; namespace Connected.ServiceModel.Transactions { internal class TransactionContext : ITransactionContext { private ConcurrentStack _operations; private MiddlewareTransactionState _state = MiddlewareTransactionState.Active; public event EventHandler? StateChanged; public MiddlewareTransactionState State { get => _state; private set { if (_state != value) { _state = value; StateChanged?.Invoke(this, EventArgs.Empty); } } } private ConcurrentStack Operations => _operations ??= new ConcurrentStack(); public bool IsDirty { get; set; } public void Register(ITransactionClient client) { if (client is null || Operations.Contains(client)) return; Operations.Push(client); } public async Task Commit() { State = MiddlewareTransactionState.Committing; while (!Operations.IsEmpty) { if (Operations.TryPop(out ITransactionClient? op)) await op?.Commit(); } State = MiddlewareTransactionState.Completed; } public async Task Rollback() { State = MiddlewareTransactionState.Reverting; while (!Operations.IsEmpty) { if (Operations.TryPop(out ITransactionClient? op)) await op?.Rollback(); } State = MiddlewareTransactionState.Completed; } } }