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