Ошибка MediatR: зарегистрируйте свои обработчики в контейнере

#c# #asp.net-core #dependency-injection #mediatr

#c# #asp.net-core #внедрение зависимостей #mediatr

Вопрос:

У меня есть приложение .Net Core, в котором я использую .Добавьте расширение MediatR для регистрации сборки для моих команд и обработчиков

В ConfigureServices в Startup.cs я использовал метод расширения из официального пакета MediatR.Extensions.Майкрософт.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;
    }
  

Класс commandhandler выглядит следующим образом:
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);
    }
  

пока никаких проблем не ожидается Посредник.Отправить (запрос); этот ответ приходит успешно

проблема начинается отсюда

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;
        }
    }
}
  

Когда выполняется эта строка в методе отправки, я получаю исключение:

 var response = await _mediator.Send(req); 
  

Ошибка построения обработчика для запроса типа
MediatR.IRequestHandler 2[IUC.BaseApplication.BLL.Handlers.Yonetim.EpostaHesaplariHandlers.ListEpostaHesaplariRequest,IUC.BaseApplication.COMMON.Models.ResultDataDto 1[System.Коллекции.Generic.List`1[IUC.BaseApplication.BLL.Models.Yonetim.EpostaHesaplariDto.ListEpostaHesaplariDto]]].
Зарегистрируйте свои обработчики в контейнере. Смотрите Примеры в GitHub
для примеров.

Комментарии:

1. Вы решили проблему? У меня такая же проблема для вас, пожалуйста, сообщите.

Ответ №1:

 services.AddMediatR(Assembly.GetExecutingAssembly());
  

Все ваши обработчики и команды находятся в этой сборке, которую вы передали?

Ответ №2:

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

Регистрация службы MediatR в Dotnet 6 в program files.

Комментарии:

1. Спасибо! В документации говорится о Assembly.GetExecutingAssembly()) том, но поскольку я использую несколько проектов, обработчики находятся не в исполняемой сборке, а в разных.

2. Здравствуйте, возможно, вы решили свою проблему, но для протокола я отвечаю: если вы хотите использовать сборки из другого проекта, вы можете получить как показано ниже, указав имя класса в этом проекте. Сборка. GetAssembly(typeof(MyMapping));

Ответ №3:

Проблема может заключаться в том, что «конструктор без параметров не определен», например MappingProfiles , для класса, унаследованного от Profile class . И это должно быть public , а не protected . Вы можете не увидеть это исключение, если ваше пользовательское промежуточное программное обеспечение скрывает внутренние исключения.

Ответ №4:

Если обработчик 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. если при открытии соединения возникает исключение