using System.Collections.Concurrent; using Connected.Interop; using Connected.ServiceModel; using Connected.ServiceModel.Transactions; namespace Connected.Services; public abstract class ServiceOperation : IServiceOperation, ITransactionClient, IOperationState where TArgs : IDto { private TArgs _arguments; protected ServiceOperation() { State = new(); } private ConcurrentDictionary State { get; } public TArgs Arguments { get => _arguments; protected set { if (value is null) throw new ArgumentException(nameof(Arguments)); _arguments = value; } } public TEntity? SetState(TEntity? entity) { var key = typeof(TEntity).FullName; if (string.IsNullOrEmpty(key)) return entity; State.AddOrUpdate(key, entity, (existing, @new) => { return @new; }); return entity; } public TEntity? GetState() { var key = typeof(TEntity).FullName; if (string.IsNullOrEmpty(key)) return default; if (!State.TryGetValue(key, out object? result)) return default; if (TypeConversion.TryConvert(result, out TEntity? entity)) return entity; return default; } async Task ITransactionClient.Commit() { await OnCommitting(); await OnCommitted(); } async Task ITransactionClient.Rollback() { await OnRollingBack(); await OnRolledBack(); } protected virtual async Task OnCommitted() { await Task.CompletedTask; } protected virtual async Task OnRolledBack() { await Task.CompletedTask; } protected virtual async Task OnCommitting() { await Task.CompletedTask; } protected virtual async Task OnRollingBack() { await Task.CompletedTask; } }