我创建了一个具有如下已知类型的请求异常处理程序,并处理了异常。我发现的唯一例子就是这样做的。
using MediatR.Pipeline;
using Microsoft.Extensions.Logging;
using MyPortal.Application.Common.Models;
using MyPortal.Application.MyCommands.Commands.CompleteMyCommand;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace MyPortal.Application.Common.Behaviors
{
public class RequestGenericExceptionHandler : IRequestExceptionHandler<MyCommand, Result>
{
private readonly ILogger<MyCommand> _logger;
public RequestGenericExceptionHandler(ILogger<MyCommand> logger)
{
_logger = logger;
}
public async Task Handle(MyCommand request,
Exception exception,
RequestExceptionHandlerState<Result> state,
CancellationToken cancellationToken)
{
var name = typeof(MyCommand).Name;
_logger.LogError("MyPortal Request Exception {@Request}",
name, exception.Message, request);
}
}
}
当我尝试使用这样的东西时,它没有被处理:
public class RequestGenericExceptionHandler<TRequest, TResponse> : IRequestExceptionHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly ILogger<TRequest> _logger;
public RequestGenericExceptionHandler(ILogger<TRequest> logger)
{
_logger = logger;
}
public async Task Handle(TRequest request,
Exception exception,
RequestExceptionHandlerState<TResponse> state,
CancellationToken cancellationToken)
{
var name = typeof(TRequest).Name;
_logger.LogError("MyPortal Request Exception {@Request}",
name, exception.Message, request);
}
}
我正在使用 .Net Core 3.1、Mediator 8.0.1 和 MediatR.Extensions.Microsoft.DependencyIntjection 8.0.0,这是我唯一的依赖注入:
services.AddMediatR(Assembly.GetExecutingAssembly());
我需要做出这些改变:
public class RequestGenericExceptionHandler<TRequest, TResponse, TException> : IRequestExceptionHandler<TRequest, TResponse, TException>
where TException : Exception {
public async Task Handle(TRequest request,
TException exception,
RequestExceptionHandlerState<TResponse> state,
CancellationToken cancellationToken) {}
}
仅在不使用时才需要此行
MediatR.Extensions.Microsoft.DependencyIntjection
:
services.AddTransient(typeof(IRequestExceptionHandler<,,>), typeof(RequestGenericExceptionHandler<,,>));
这样的事情应该有效。此外,如果您想返回异常的通用响应,您可以让所有响应类实现相同的接口,然后返回一个通用的接口
public class GenericRequestExceptionHandler<TRequest, TResponse, TException> : IRequestExceptionHandler<TRequest, TResponse, TException>
where TRequest : IRequest
where TResponse : Result
where TException : Exception
{
private readonly ILogger<TRequest> _logger;
public GenericRequestExceptionHandler(ILogger<TRequest> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(TRequest request, TException exception, RequestExceptionHandlerState<TResponse> state, CancellationToken cancellationToken = new CancellationToken())
{
_logger.LogError(exception, $"Error occurs on handling {nameof(TRequest)}");
await Task.Run(() => state.SetHandled((TResponse)Result.Failure(new string[] { exception.Message })));
}
}