该程序无法找到 MediatR 查询 ASP.Net Core 的处理程序

Posted

技术标签:

【中文标题】该程序无法找到 MediatR 查询 ASP.Net Core 的处理程序【英文标题】:the program is not able to find handler for MediatR query ASP.Net Core 【发布时间】:2019-10-18 07:19:12 【问题描述】:

我将 ASP.Net Core 2.2 和 MediatR 框架/库用于查询对象。当我运行程序时,我遇到了这个异常:

InvalidOperationException:未找到类型请求的处理程序 MediatR.IRequestHandler2[Store.Core.Queries.GetProductTypesQuery,System.Collections.Generic.IEnumerable1[Store.Core.DomainModels.ProductType]]。 向容器注册您的处理程序。

我将这些打包添加到我的 Store 项目(主项目)中

1- MediatR 7.0.0

2- MediatR.Extensions.Microsoft.DependencyInjection

这是我的 Startup.cs

services.AddMediatR(typeof(Startup));

这是我的查询(位于名为“Store.Core”的项目中)

namespace Store.Core.Queries.Products

   public class GetProductTypesQuery : IRequest<IEnumerable<ProductType>>  

这是我的 QueryHandler(位于另一个名为“Store.Data”的项目中)

namespace Data.Queries.Products

    public class GetProductTypesQueryHandler : IRequestHandler<GetProductTypesQuery, IEnumerable<ProductType>>
    
        private ApplicationDbContext _context;
        public GetProductTypesQueryHandler(ApplicationDbContext context)
        
            _context = context;
        

        public async Task<IEnumerable<ProductType>> Handle(GetProductTypesQuery request, CancellationToken cancellationToken)
        
            return await _context.ProductType.OrderBy(p => p.ProductTypeID).ToListAsync();
        

    

这是我使用 MediatR 的控制器

namespace Store.Controllers

    public class HomeController : Controller
    
        private readonly IMapper _mapper;
        private readonly IMediator _mediator;
        public HomeController(IMapper mapper, IMediator mediator)
        
            _mapper = mapper;
            _mediator = mediator;   
        


        public IActionResult Home() => View();

        [HttpGet]
        public async Task<IActionResult> Dishes(GetProductTypesQuery query) 
            var productTypes = await _mediator.Send(query);
            var productTypesViewModel = _mapper.Map<IEnumerable<ProductTypeVM>>(productTypes);
            return View(productTypesViewModel);
        


我的 ProductType 模型(我认为没有必要,但我添加它是为了提供完整信息)

namespace Store.Core.DomainModels

    public class ProductType
    
       public int ProductID  get; set; 
       public string ProductName  get; set; 
    

对我来说唯一可疑的部分是 StartUp.cs(因为我在不同的项目中有查询和查询处理程序)但我不知道我缺少什么。

【问题讨论】:

【参考方案1】:

正如我所猜测的,问题出在您添加 MediatR 服务的 Startup.cs。由于我的处理程序位于单独的程序集中,因此我们应该提及该程序集名称。 我在 Startup.cs 中更改了这个

public void ConfigureServices(IServiceCollection services) 
    services.AddMediatR(typeof(Startup));

到这里:

public void ConfigureServices(IServiceCollection services)
    var assembly = AppDomain.CurrentDomain.Load("Data");
    services.AddMediatR(assembly);

这里的“数据”是我的程序集的名称,所有处理程序都存储在那里。

【讨论】:

在我的一个项目中,我喜欢这个services.AddMediatR(); 并且运行良好。如上所示,我必须使用另一个具有精确配置和 NuGet 包的项目。谢谢,它解决了我的问题,但为什么我的其他项目没有程序集输入。它们在两个项目中都有相同的命名空间。【参考方案2】:

我需要使用:

services.AddMediatR(typeof(DeletePeopleCommand).GetTypeInfo().Assembly);

【讨论】:

【参考方案3】:

你可以用这个

public void ConfigureServices(IServiceCollection services)
        services.AddMediatR(AppDomain.CurrentDomain.GetAssemblies());
    

这里 GetAssemblies() 将加载所有处理程序类。

【讨论】:

我试试这个,但它不会加载处理程序。相反,我按名称获取程序集并且它可以工作: services.AddMediatR(AppDomain.CurrentDomain.Load("Data"))【参考方案4】:

我遇到了这个错误。

像个傻瓜一样,我忘记让我的处理程序实现IRequestHandler&lt;TRequest, TResponse&gt;,没有它容器就不会寻找处理程序。

【讨论】:

【参考方案5】:

确保您的处理程序是公开的。

【讨论】:

【参考方案6】:

如果我们的RequestHandler在其他csproj中也可能会出现问题。

我们必须在启动时找到所有这些程序集,并注册一个正确的方式。

【讨论】:

以上是关于该程序无法找到 MediatR 查询 ASP.Net Core 的处理程序的主要内容,如果未能解决你的问题,请参考以下文章

无法为 MediatR 设置起订量回调

具有通用处理程序和查询的 Mediatr

如何取消 MediatR 发送的查询?

MediatR - 处理查询中的当前用户

使用 MediatR 链接处理程序

Mediatr:单元测试行为/验证