.NET Core 7 Minimal API MediatR Ошибка сопоставления обработчика запросов IRequest

В настоящее время я получаю следующую ошибку при выполнении команды через .NET Core 7 Minimal API:

 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.InvalidOperationException: Error constructing handler for request of type MediatR.IRequestHandler`2[mNet.FileServer.Commands.Core.Application.Features.
StoredFileTypes.NewStoredFileType.NewStoredFileTypeCommand,mNet.Common.Core.Application.Commands.BaseCommandResponse`1[mNet.FileServer.Shared.Core.Domain.StoredFile
Types.ValueObjects.StoredFileTypeId]]. Register your handlers with the container. See the samples in GitHub for examples.
       ---> System.InvalidOperationException: No service for type 'MediatR.IRequestHandler`2[mNet.FileServer.Commands.Core.Application.Features.StoredFileTypes.NewS
toredFileType.NewStoredFileTypeCommand,mNet.Common.Core.Application.Commands.BaseCommandResponse`1[mNet.FileServer.Shared.Core.Domain.StoredFileTypes.ValueObjects.S
toredFileTypeId]]' has been registered.
         at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
         at MediatR.ServiceFactoryExtensions.GetInstance[T](ServiceFactory factory)
         at MediatR.Wrappers.HandlerBase.GetHandler[THandler](ServiceFactory factory)
         --- End of inner exception stack trace ---
         at MediatR.Wrappers.HandlerBase.GetHandler[THandler](ServiceFactory factory)
         at MediatR.Wrappers.RequestHandlerWrapperImpl`2.<>c__DisplayClass1_0.<Handle>g__Handler|0()
         at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.Handle(TRequest request, RequestHandlerDelegate`1 next, CancellationToken cancellationToken)
         at MediatR.Pipeline.RequestExceptionProcessorBehavior`2.Handle(TRequest request, RequestHandlerDelegate`1 next, CancellationToken cancellationToken)
         at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.Handle(TRequest request, RequestHandlerDelegate`1 next, CancellationToken cancellationToken)
         at MediatR.Pipeline.RequestExceptionActionProcessorBehavior`2.Handle(TRequest request, RequestHandlerDelegate`1 next, CancellationToken cancellationToken)
         at MediatR.Pipeline.RequestPostProcessorBehavior`2.Handle(TRequest request, RequestHandlerDelegate`1 next, CancellationToken cancellationToken)
         at MediatR.Pipeline.RequestPreProcessorBehavior`2.Handle(TRequest request, RequestHandlerDelegate`1 next, CancellationToken cancellationToken)
         at mNet.FileServer.Commands.Ui.MinimalApi.Endpoints.StoredFileTypeEndpoint.NewStoredFileTypeAsync(NewStoredFileTypeDto request, IMediator mediator) in C:\U
sers\dcmea\OneDrive\mNet Microservices\mNet.FileServer\mNet.FileServer.Commands.Ui.MinimalApi\Endpoints\StoredFileTypeEndpoint.cs:line 47
         at Microsoft.AspNetCore.Http.RequestDelegateFactory.<ExecuteTaskOfT>g__ExecuteAwaited|111_0[T](Task`1 task, HttpContext httpContext)
         at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass89_2.<<HandleRequestBodyAndCompileRequestDelegateForJson>b__2>d.MoveNext()
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
         at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
         at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

Ключевые части кода находятся в следующих проектах и ​​заключаются в следующем:

  • mNet.Common.Core.Application: содержит классы BaseCommand и BaseCommandResponse.
  • mNet.FileServer.Shared.Core.Domain: содержит объект значения StoredFileTypeId.
  • mNet.FileServer.Commands.Core.Domain: содержит совокупность StoredFileType
  • mNet.FileServer.Commands.Core.Application: содержит классы NewStoredFileTypeCommand и NewStoredFileTypeCommandHandler.
  • mNet.FileServer.Commands.Ui.MinimalApi: содержит основные Program.cs и минимальные конечные точки API.

Ключевые классы:

Program.cs (извлечение)

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

Минимальная конечная точка API

private static async Task<BaseCommandResponse<StoredFileTypeId>> NewStoredFileTypeAsync(NewStoredFileTypeDto request, IMediator mediator)
    {
        var messageId = Guid.NewGuid();
        var command = new NewStoredFileTypeCommand
        {
            Id = new MessageId(messageId),
            CorrelationId = new CorrelationId(messageId),
            CausationId = new CausationId(messageId),
            CommandDto = request
        };

        var response = await mediator.Send(command); //Error happens after this MediatR call and is line 47 as referenced in the error
        return response;

    }

Ньюсторедфилетипекомманд

public class NewStoredFileTypeCommand : BaseCommand, IRequest<BaseCommandResponse<StoredFileTypeId>>
{
    public NewStoredFileTypeDto CommandDto { get; init; } = default!;
}

Ньюсторедфилетипекоммандхандлер

public class NewStoredFileTypeCommandHandler : IRequestHandler<NewStoredFileTypeCommand, BaseCommandResponse<StoredFileTypeId>>
{
    private readonly IMapper _mapper;
    private readonly IEventSourcingHandler<StoredFileType, StoredFileTypeId> _eventSourcingHandler;

    public NewStoredFileTypeCommandHandler(IMapper mapper,
        IEventSourcingHandler<StoredFileType, StoredFileTypeId> eventSourcingHandler)
    {
        _mapper = mapper;
        _eventSourcingHandler = eventSourcingHandler;
    }

    public async Task<BaseCommandResponse<StoredFileTypeId>> Handle(NewStoredFileTypeCommand request, CancellationToken cancellationToken)
    {
       var response = new BaseCommandResponse<StoredFileTypeId>();

        var aggregate = new StoredFileType(
            new StoredFileTypeId(Guid.NewGuid()), 
            request.CorrelationId, 
            new CausationId(request.Id.Id),
            request.CommandDto.Name, 
            request.CommandDto.IsImageFileType,
            _mapper.Map<BootstrapIconCode>(request.CommandDto.BootstrapIconCode),
            _mapper.Map<MimeType>(request.CommandDto.MimeType)
            );
        
        await _eventSourcingHandler.SaveAsync(aggregate);

        response.Id = aggregate.Id;
        response.Message = $"Created new {nameof(StoredFileType)} aggregate!";
        response.IsSuccessful = true;

        return response;


    }

Судя по нескольким отладочным трассировкам, кажется, что MediatR не сопоставляет NewStoredFileTypeCommandHandler с NewStoredFileTypeCommand, и я не могу понять, почему.

Кроме того, как я объявил AppDomain.CurrentDomain.GetAssemblies() в Program.cs, это не должно быть областью действия.

Любые идеи будут оценены по достоинству, так как это сводит меня с ума!

Конечные и Readonly классы в PHP
Конечные и Readonly классы в PHP
В прошлом, когда вы не хотели, чтобы другие классы расширяли определенный класс, вы могли пометить его как final.
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
БЭМ: Конвенция об именовании CSS
БЭМ: Конвенция об именовании CSS
Я часто вижу беспорядочный код CSS, особенно если проект большой. Кроме того, я совершал эту ошибку в профессиональных или личных проектах и...
Революционная веб-разработка ServiceNow
Революционная веб-разработка ServiceNow
В быстро развивающемся мире веб-разработки ServiceNow для достижения успеха крайне важно оставаться на вершине последних тенденций и технологий. По...
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Заголовок веб-страницы играет наиболее важную роль в SEO, он помогает поисковой системе понять, о чем ваш сайт.
Конфигурация Jest в angular
Конфигурация Jest в angular
В этой статье я рассказываю обо всех необходимых шагах, которые нужно выполнить при настройке jest в angular.
2
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мое предположение основано на следующей цитате из документации для AppDomain.GetAssemblies:

Получает сборки, которые были загружены в контекст выполнения этого домена приложения.

Есть вероятность, что соответствующая сборка еще не загружена в домен приложения. Попробуйте использовать AddMediatr и предоставить сборки/типы из сборок, хранящих части mediatr:

// use a type per assembly containing the MediatR components
builder.Services.AddMediatR(typeof(NewStoredFileTypeCommandHandler), typeof(BaseCommand), ...);

Спасибо - это сработало отлично! Есть ли способ принудительно загрузить сборки? Будет сложно добавить эту строку для каждого обработчика команд.

dmeadley 14.02.2023 11:01

@dmeadley - рад был помочь! Если ответ работает для вас - смело отмечайте его как принятый) "Есть ли способ принудительно загрузить сборки" - да, вам нужно использовать тип из него). «Будет мучительно добавлять эту строку для каждого обработчика команд» - насколько я знаю, вам это не нужно, вам нужна только одна сборка (насколько я помню, Mediatr использует тип, чтобы получить свою сборку и загрузить все необходимое компоненты Mediatr).

Guru Stron 14.02.2023 11:05

Спасибо за это @Guru Stron. Я посмотрю, как я могу использовать тип из него при загрузке, чтобы мне не приходилось помнить о добавлении одного на сборку.

dmeadley 14.02.2023 11:13

@dmeadley typeof(SomeType) - на самом деле это использование. Я бы рекомендовал придерживаться кода в ответе, потому что не будет никакой разницы с точки зрения «необходимости помнить». А использование типов для загрузки сборки перед AddMediatR — довольно хрупкий подход (зависит от порядка, поведения во время выполнения и т. д.). Я бы сказал, что подход AddMediatR с одним типом на сборку намного чище и удобнее в сопровождении.

Guru Stron 14.02.2023 11:18

Другие вопросы по теме

Похожие вопросы