public virtual async Task <ServiceResponse <TResponse> > Execute(TRequest request, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException(nameof(request)); } StartTime = ServiceClock.CurrentTime(); _chainedServiceResolver?.AddCallToChain(this); _correlationId = CalculateCorrelationId(request); _sessionId = request.SessionId; _serviceHop = CalculateServiceHop(); request.CorrelationId = _correlationId; request.SyncCorrelationIds(); ServiceResponse <TResponse> response = null; // ON REQUEST PIPELINE _logger.LogTrace($"Start request pipeline for {request.CorrelationId}"); foreach (var middleware in _pipeline) { try { if (_serviceHop > 0 && middleware.SkipOnInternalCall) { continue; } var middlewareResult = await middleware.OnRequest(this, request, cancellationToken); if (middlewareResult != null) { response = new ServiceResponse <TResponse>(default(TResponse), middlewareResult.MetaData); break; } } catch (Exception ex) { if (!middleware.IgnoreExceptions) { var errorResponse = PermanentError(ex); StoredResponse = errorResponse; return(errorResponse); } } } _logger.LogTrace($"End request pipeline for {request.CorrelationId}"); // EXECUTE THE SERVICE _logger.LogTrace($"Start execute for {request.CorrelationId}"); try { if (!cancellationToken.IsCancellationRequested) { if (response == null) { response = await BeforeImplementation(request, cancellationToken); } } else { response = TemporaryException("Cancellation Request:BeforeImplementation"); } if (!cancellationToken.IsCancellationRequested) { if (response == null) { response = await Implementation(request, cancellationToken); } } else { response = TemporaryException("Cancellation Requested:Implementation"); } } catch (NotImplementedException ex) { _logger.LogInformation(ex, $"Call path is not implemented: {request.CorrelationId}"); response = new ServiceResponse <TResponse>( default(TResponse), new ResponseMetaData(this, ServiceResult.NotImplemented)); } catch (BusinessLogicException ex) { response = new ServiceResponse <TResponse>( default(TResponse), new ResponseMetaData(this, ex.Result, publicMessage: ex.PublicMessage, exceptionMessage: ex.ToString())); } catch (ValidationErrorException ex) { response = ValidationError(ex.Error, ex.Member); } catch (Exception ex) { response = PermanentError(ex); } _logger.LogTrace($"End execute for {request.CorrelationId}"); _logger.LogTrace($"Start response pipeline for {request.CorrelationId}"); // ON RESPONSE PIPELINE for (var i = _pipeline.Count - 1; i >= 0; i--) { var middleware = _pipeline[i]; if (_serviceHop > 0 && middleware.SkipOnInternalCall) { continue; } try { await middleware.OnResponse(this, request, response, cancellationToken); } catch (Exception ex) { if (!middleware.IgnoreExceptions) { var errorResponse = PermanentError(ex); StoredResponse = errorResponse; return(errorResponse); } } } _logger.LogTrace($"End response pipeline for {request.CorrelationId}"); await BeforeResponse(response, cancellationToken); StoredResponse = response; return(response); }
protected virtual Task BeforeResponse(ServiceResponse <TResponse> response, CancellationToken cancellationToken) { return(Task.CompletedTask); }