using Connected; using Connected.Notifications.Events; namespace Common.Documents; public abstract class DocumentListener : EventListener where TArgs : IDto where TDocument : IDocument where TPrimaryKey : notnull { public DocumentListener(IDocumentLocker locker) { Locker = locker; } private IDocumentLocker Locker { get; } protected abstract TDocument Document { get; } protected override async Task OnInvoke() { await OnPreparing(); if (Document is null) return; Locker.Expired += async (s, e) => { await OnException(new TimeoutException()); }; try { await Locker.Lock(Document); await OnInvoking(); await Locker.Unlock(); } catch (Exception ex) { await Locker.Unlock(); await OnException(ex); } } protected virtual async Task OnPreparing() { await Task.CompletedTask; return false; } protected virtual async Task OnInvoking() { await Task.CompletedTask; } protected virtual async Task OnException(Exception ex) { await Task.CompletedTask; } protected override void OnDisposing() { Locker.Dispose(); } }