using System.Diagnostics; using HrynCo.NotificationService.DAL.Abstract; using MediatR; using Microsoft.Extensions.Logging; namespace HrynCo.NotificationService.Services.Behaviors; public class TransactionBehavior : IPipelineBehavior where TRequest : notnull { private readonly IUnitOfWork _unitOfWork; private readonly ILogger> _logger; public TransactionBehavior(IUnitOfWork unitOfWork, ILogger> logger) { _unitOfWork = unitOfWork; _logger = logger; } public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) { string handlerName = typeof(TRequest).Name; _logger.LogDebug("Handling {Handler}", handlerName); Stopwatch sw = Stopwatch.StartNew(); try { TResponse result = await _unitOfWork.ExecuteInTransactionAsync(async () => { TResponse response = await next(); await _unitOfWork.SaveChangesAsync(cancellationToken); return response; }); _logger.LogDebug("Handled {Handler} in {ElapsedMs}ms", handlerName, sw.ElapsedMilliseconds); return result; } catch (Exception ex) { _logger.LogError(ex, "Handler {Handler} failed after {ElapsedMs}ms", handlerName, sw.ElapsedMilliseconds); throw; } } }