Всем добра!
Стек: ASP.Net Core .NET 6, MediatR.
Суть проблемы: есть много обработчиков которые обращаются к одной сущности, но с разными параметрами запроса и разными возвращаемыми типами.
Появилась мысль вынести параметры запроса в Спецификацию и сделать универсальный Generic - обработчик, который будет применять Спецификацию и маппить результат в нужный тип.
Пример того что у меня получилось:
// Query
namespace UserAPI.App
{
public sealed record PersonsQuery<TResult>(Specification<Person> Specification) : IRequest<IEnumerable<TResult>>;
}
// Request Handler
namespace UserAPI.App
{
public class PersonHandler<TResult> : IRequestHandler<PersonsQuery<TResult>, IEnumerable<TResult>>
{
private readonly IMapper _mapper;
public PersonHandler(IMapper mapper)
{
_mapper = mapper;
}
public async Task<IEnumerable<TResult>> Handle(PersonsQuery<TResult> request, CancellationToken cancellationToken)
{
var query = SpecificationEvaluator.GetQuery(DB.Persons, request.Specification).AsQueryable().ProjectTo<TResult>(_mapper.ConfigurationProvider);
return query;
}
}
}
// In Program.cs
builder.Services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssemblyContaining(typeof(Program));
});
// Вызов
var model = await _mediator.Send(new PersonsQuery<PersonResponse>(new PersonEvenIdSpecification()));
На выходе получаю исключение: InvalidOperationException: No service for type 'MediatR.IRequestHandler`2[UserAPI.App.PersonsQuery`1[UserAPI.Models.PersonResponse],System.Collections.Generic.IEnumerable`1[UserAPI.Models.PersonResponse]]' has been registered.
Нашел один вариант
github, но в нем нужно создавать отдельные обработчики под каждый тип, чего делать не хочется)
Есть ли вариант использовать, все таки, один обработчик?