public async Task <TResponse> Handle(TRequest request, CancellationToken cancellationToken,
                                             RequestHandlerDelegate <TResponse> next)
        {
            TResponse response = await next();

            var events = _dbContext.GetDomainEvents().ToList();

            foreach (var @event in events)
            {
                //@publish those events somewhere
            }

            return(response);
        }
        public async Task <TResponse> Handle(TRequest request,
                                             CancellationToken cancellationToken,
                                             RequestHandlerDelegate <TResponse> next)
        {
            var transactionAttr = _outerHandler
                                  .GetType()
                                  ?.GetTypeInfo()
                                  ?.GetDeclaredMethod("Handle")
                                  ?.GetCustomAttributes(typeof(TransactionScopeAttribute), true);

            if (transactionAttr != null && transactionAttr.Length < 1)
            {
                _logger.LogInformation($"Handled {typeof(TRequest).FullName}");
                return(await next());
            }

            _logger.LogInformation($"Handling command {typeof(TRequest).FullName}");
            _logger.LogDebug($"Handling command {typeof(TRequest).FullName} with content {JsonSerializer.Serialize(request)}");
            _logger.LogInformation($"Open the transaction for {typeof(TRequest).FullName}.");
            var strategy = _dbFacadeResolver.Database.CreateExecutionStrategy();

            return(await strategy.ExecuteAsync(async() =>
            {
                // Achieving atomicity
                await using var transaction = _dbFacadeResolver.Database.BeginTransaction(IsolationLevel.ReadCommitted);

                _logger.LogInformation($"Executing the {typeof(TRequest).FullName} request.");
                var response = await next();

                await transaction.CommitAsync(cancellationToken);

                _logger.LogInformation($"Publishing domain events for {typeof(TRequest).FullName}.");
                var domainEvents = _domainEventContext.GetDomainEvents().ToList();

                var tasks = domainEvents
                            .Select(async @event =>
                {
                    _logger.LogInformation($"Publishing domain event {@event.GetType().FullName}...");
                    _logger.LogDebug(
                        $"Publishing domain event {@event.GetType().FullName} with payload {JsonSerializer.Serialize(@event)}");
                    await _mediator.Publish(@event, cancellationToken);
                    _logger.LogInformation($"Published domain event {@event.GetType().FullName}.");
                });

                await Task.WhenAll(tasks);

                _logger.LogInformation($"Handled {typeof(TRequest).FullName}");
                return response;
            }));
        }
Example #3
0
        public async Task <TResponse> Handle(TRequest request, CancellationToken cancellationToken,
                                             RequestHandlerDelegate <TResponse> next)
        {
            if (request is not ITxRequest)
            {
                return(await next());
            }

            _logger.LogInformation("{Prefix} Handled command {MediatRRequest}", nameof(TxBehavior <TRequest, TResponse>), typeof(TRequest).FullName);
            _logger.LogDebug("{Prefix} Handled command {MediatRRequest} with content {RequestContent}", nameof(TxBehavior <TRequest, TResponse>), typeof(TRequest).FullName, JsonSerializer.Serialize(request));
            _logger.LogInformation("{Prefix} Open the transaction for {MediatRRequest}", nameof(TxBehavior <TRequest, TResponse>), typeof(TRequest).FullName);
            var strategy = _dbFacadeResolver.Database.CreateExecutionStrategy();

            return(await strategy.ExecuteAsync(async() =>
            {
                // Achieving atomicity
                await using var transaction = await _dbFacadeResolver.Database.BeginTransactionAsync(IsolationLevel.ReadCommitted, cancellationToken);

                var response = await next();
                _logger.LogInformation("{Prefix} Executed the {MediatRRequest} request", nameof(TxBehavior <TRequest, TResponse>), typeof(TRequest).FullName);

                await transaction.CommitAsync(cancellationToken);

                var domainEvents = _domainEventContext.GetDomainEvents().ToList();
                _logger.LogInformation("{Prefix} Published domain events for {MediatRRequest}", nameof(TxBehavior <TRequest, TResponse>), typeof(TRequest).FullName);

                var tasks = domainEvents
                            .Select(async @event =>
                {
                    // because we have int identity
                    var id = (response as dynamic)?.Id;
                    @event.MetaData.Add("id", id);

                    await _mediator.Publish(@event, cancellationToken);
                    _logger.LogDebug(
                        "{Prefix} Published domain event {DomainEventName} with payload {DomainEventContent}", nameof(TxBehavior <TRequest, TResponse>), @event.GetType().FullName, JsonSerializer.Serialize(@event));
                });

                await Task.WhenAll(tasks);

                return response;
            }));
        }