MediatR错误:使用容器注册您的处理程序

3

我有一个 .Net Core 应用程序,其中我使用 .AddMediatR 扩展来注册我的命令和处理程序的程序集。

在 Startup.cs 的 ConfigureServices 中,我使用了官方包 MediatR.Extensions.Microsoft.DependencyInjection 的扩展方法,并使用以下参数:

startup.cs

 services.AddBLL();

DependencyInjection.cs

public static IServiceCollection AddBLL(this IServiceCollection services)
    {
        services.AddAutoMapper(Assembly.GetExecutingAssembly());
        services.AddMediatR(Assembly.GetExecutingAssembly());
        services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPerformanceBehaviour<,>));
        services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestValidationBehavior<,>));

        return services;
    }

命令处理程序类如下所示: ListEpostaHesaplariHandler.cs

public class ListEpostaHesaplariRequest : IRequest<ResultDataDto<List<ListEpostaHesaplariDto>>>
{
    public FiltreEpostaHesaplariDto Model { get; set; }
}

public class ListEpostaHesaplariHandler : IRequestHandler<ListEpostaHesaplariRequest, ResultDataDto<List<ListEpostaHesaplariDto>>>
{
    private readonly IBaseDbContext _context;
    private readonly IMapper _mapper;

    public ListEpostaHesaplariHandler(IBaseDbContext context, IMapper mapper)
    {
        _context = context;
        _mapper = mapper;
    }

    public async Task<ResultDataDto<List<ListEpostaHesaplariDto>>> Handle(ListEpostaHesaplariRequest request, CancellationToken cancellationToken)
    {
        await Task.Delay(1);

        var resultDataDto = new ResultDataDto<List<ListEpostaHesaplariDto>>() { Status = ResultStatus.Success };

        try
        {
            var foo = _context.EpostaHesaplari;

            var filtreliEpostaHesaplari = Filtre(request.Model, foo);

            var epostaHesaplariDto = _mapper.Map<List<ListEpostaHesaplariDto>>(filtreliEpostaHesaplari);

            resultDataDto.Result = epostaHesaplariDto;
        }
        catch (Exception ex)
        {
            resultDataDto.Status = ResultStatus.Error;
            resultDataDto.AddError(ex.Message);
        }

        return resultDataDto;
    }

这是我使用MediatR的控制器

BaseController.cs

  public abstract class BaseController : Controller
{
    private IMediator _mediator;
    public static int? birimIDD;
    protected IMediator Mediator
    {
        get
        {
            return _mediator ??= HttpContext.RequestServices.GetService<IMediator>();
        }
    }
}

HomeController.cs

[HttpPost]
    public async Task<IActionResult> MailGonderAsync()
    {

        FiltreEpostaHesaplariDto filtre = new FiltreEpostaHesaplariDto();
        filtre.Durum = true;
        var req = new ListEpostaHesaplariRequest() { Model = filtre };
        var response = await Mediator.Send(req);
    }

到目前为止没有问题,等待Mediator.Send(req);请求已成功返回响应。

问题从这里开始:

send.cs(业务逻辑层中的类)

public class EmailSend : IEmailSingleSender
{
    private readonly IMediator _mediator;

    public EmailSend(IMediator mediator)
    {
        _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));

    }

    public async Task Send(EmailParamsDto emailParamsDto)
    {
        try
        {
            FiltreEpostaHesaplariDto filtre = new FiltreEpostaHesaplariDto();
            filtre.Durum = true;
            var req = new ListEpostaHesaplariRequest() { Model = filtre };
            var response = await _mediator.Send(req);

            SmtpClient smtpClient = new SmtpClient();
            smtpClient.Port = _emailSetting.Port;
            smtpClient.Host = _emailSetting.Server;
            smtpClient.EnableSsl = _emailSetting.UseSsl;
            NetworkCredential networkCredential = new NetworkCredential();
            networkCredential.UserName = _emailSetting.UserName;
            networkCredential.Password = _emailSetting.Password;
            smtpClient.Credentials = networkCredential;
            MailMessage mail = new MailMessage();
            mail.IsBodyHtml = _emailSetting.IsHtml;
            mail.From = new MailAddress(_emailSetting.UserName, emailParamsDto.Subject);
            mail.To.Add(new MailAddress(emailParamsDto.Receiver));
            //mail.CC.Add(_emailSetting.AdminMail);
            mail.Body = emailParamsDto.Body;
            mail.Subject = emailParamsDto.Subject;
            mail.Priority = emailParamsDto.MailPriority;

            await smtpClient.SendMailAsync(mail);
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }
}

当执行 Send 方法中的这行代码时,我会收到异常:
var response = await _mediator.Send(req); 

构造处理程序时出错,请求类型为MediatR.IRequestHandler2[IUC.BaseApplication.BLL.Handlers.Yonetim.EpostaHesaplariHandlers.ListEpostaHesaplariRequest,IUC.BaseApplication.COMMON.Models.ResultDataDto1[System.Collections.Generic.List`1[IUC.BaseApplication.BLL.Models.Yonetim.EpostaHesaplariDto.ListEpostaHesaplariDto]]]>。请在容器中注册处理程序。有关示例,请参见GitHub上的示例。


你解决了这个问题吗?我也遇到了同样的问题,请给予建议。 - jack.pop
5个回答

7
services.AddMediatR(Assembly.GetExecutingAssembly());

你的所有处理程序和命令都在你传递的这个程序集中吗?

3
builder.Services.AddMediatR(AppDomain.CurrentDomain.GetAssemblies());

在Dotnet 6中,将MediatR服务注册到程序文件中。

谢谢!文档中提到了 Assembly.GetExecutingAssembly(),但由于我使用多个项目,处理程序不在执行程序集中,而是在其他程序集中。 - Devator
1
你好,也许你已经解决了你的问题,但是为了记录,我来回答一下:如果你想要使用另一个项目中的程序集,你可以通过在该项目中给出类的名称来获取如下内容。Assembly.GetAssembly(typeof(MyMapping)); - kargarf

0
如果 MediateR 处理程序通过 DI 注入任何对象,而该 DI 对象的构造函数引发异常,则您也会遇到此错误。 例如,MediateR 处理程序已注入 IRepository,并且 IRepository 构造函数正在尝试打开数据库连接,但引发了异常,则会遇到“构造类型为 MediatR 的请求的处理程序时出错”的错误。
    public class MyHandler : IRequestHandler<Command, Result>
    {

        private readonly IRepository _myRepo;
        private readonly IMapper _mapper;

        public MyHandler(IRepository myRepo, IMapper mapper)
        {

            _myRepo = myRepo;
            _mapper = mapper;
        }
    }

仓库代码是

public class MyRepository : IRepository
{
    private IDbConnection _connection;
    private readonly IConfiguration _configuration;

    public MyRepository(IConfiguration configuration)
    {
            _configuration = configuration;
            string connStr = _configuration.GetConnectionString("DefaultConnection")
            _connection = new OracleConnection(connStr);

            _connection.Open(); // if this line throws exception
    }
}

_connection.Open(); 会在打开连接时导致构造处理程序出错,请求类型为 MediatR


0
问题可能是因为例如MappingProfiles类继承自Profile类时没有定义无参数构造函数。而且它必须是public,而不是protected。如果您的自定义中间件隐藏了内部异常,则可能看不到此异常。

0
  public class TestQueryHandler : IRequestHandler<TestQuery, int>
{
    public Task<int> Handle(TestQuery request, CancellationToken cancellationToken)
    {
        return Task.FromResult(10);
    }
}
Assembly myTestQueryHandlerAssebmly = typeof(TestQueryHandler).Assembly;  //Reg my Handler
builder.Services.AddTransient<TestQueryHandler, TestQueryHandler>();
builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(myTestQueryHandlerAssebmly));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接