ASP.NET Core MediatR 错误:向容器注册处理程序

Posted

技术标签:

【中文标题】ASP.NET Core MediatR 错误:向容器注册处理程序【英文标题】:ASP.NET Core MediatR error: Register your handlers with the container 【发布时间】:2018-11-19 07:21:54 【问题描述】:

我有一个 .Net Core 应用程序,我在其中使用 .AddMediatR 扩展名按照 CQRS 方法为我的命令和处理程序注册程序集。

在 Startup.cs 的 ConfigureServices 中,我使用了来自官方包 MediatR.Extensions.Microsoft.DependencyInjection 的扩展方法,带有以下参数:

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

command 和 commandhandler 类如下:

AddEducationCommand.cs

public class AddEducationCommand : IRequest<bool>

    [DataMember]
    public int UniversityId  get; set; 

    [DataMember]
    public int FacultyId  get; set; 

    [DataMember]
    public string Name  get; set; 

AddEducationCommandHandler.cs

public class AddEducationCommandHandler : IRequestHandler<AddEducationCommand, bool>
    
        private readonly IUniversityRepository _repository;
        public AddEducationCommandHandler(IUniversityRepository repository)
        
            _repository = repository;
        

        public async Task<bool> Handle(AddEducationCommand command, CancellationToken cancellationToken)
        
            var university = await _repository.GetAsync(command.UniversityId);

            university.Faculties
                .FirstOrDefault(f => f.Id == command.FacultyId)
                .CreateEducation(command.Name);

            return await _repository.UnitOfWork.SaveEntitiesAsync();
        
    

当我运行执行简单 await _mediator.Send(command); 代码的 REST 端点时,我的日志中出现以下错误:

Error constructing handler for request of type MediatR.IRequestHandler`2[UniversityService.Application.Commands.AddEducationCommand,System.Boolean]. Register your handlers withthe container. See the samples in GitHub for examples.

我试图浏览文档中的官方示例,但没有任何运气。有谁知道我如何配置 MediatR 才能正常工作?提前致谢。

【问题讨论】:

除了问题中发布的内容之外,还有很多事情可能会出错。请提供Minimal, Complete, and Verifiable example,以便我们看到您在做什么。 你应该去那里github.com/jbogard/MediatR/blob/master/samples/…,因为要注册 mediatr 及其处理程序还有很多代码要编写。 附加调试器并检查 InnerException。难道是 IUniversityRepository 没有注册,因此 RequestHandler 无法构造? services.AddMediatR() 还不够,还需要在 services 集合中注册所有其他依赖项。 谢谢彼得,我的 Autofac 模块配置中的存储库配置存在问题。 【参考方案1】:

我遇到了同样的问题。

问题在于这行代码

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

处理所有 MediatR IRequest 和 IRequestHandlers。

但是您创建了一个 IRepository 接口及其实现类,而 MediatR.Extensions.Microsoft.DependencyInjection 无法处理它

所以保留所有更改,但添加这个 - 手动注册这个像

services.AddScoped(typeof(IUniversityRepository), typeof(UniversitySqlServerRepository));

然后问题解决了。

【讨论】:

在我的情况下,InnerException 告诉我我的依赖项找不到它自己的特定版本的依赖项(例如,UniversitySqlServerRepository 找不到 Newtonsoft.Json)。【参考方案2】:

我遇到了同样的问题并搜索了几个小时但没有找到,因为这个错误是一个非常普遍的错误。显然它看起来像 MediatR 问题,但通常情况并非如此。

我是如何得出这个结论的?

为了获取原始异常,我打开了 Event Viewer 应用程序,该应用程序默认存在于 windows 中

custom Views &gt; Summary Page Events 中我发现了一些错误,这与我的应用程序相对应。在我的情况下,错误是这样的:

An error occured during migration

Exception: 
System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString')
   at Microsoft.EntityFrameworkCore.Utilities.Check.NotEmpty(String value, String parameterName)
   at Microsoft.EntityFrameworkCore.mysqlDbContextOptionsExtensions.UseMySql(DbContextOptionsBuilder optionsBuilder, String connectionString, Action`1 mySqlOptionsAction)

正如错误所说,connectionString 是空的。最终我发现当我发布我的应用程序以获取 dll 时,appsettings.json 不在发布的文件夹中,因此找不到connectionString,这就是迁移失败的原因。最终,应用程序因一个非常普遍的错误而崩溃:

Error constructing handler for request of type MediatR.IRequestHandler. 

Register your handlers with the container. See the samples in GitHub for examples

【讨论】:

你为我节省了很多时间。谢谢!!你是如何添加 appsettings.json 的? @samantha07 感谢您的赞赏 :) 由于一些错误,appsettings.json 包含在 .gitignore 文件中。因此,它没有被推送到 bitbucket 服务器上,最终当我从 bitbucket 管道生成构建时,appsettings.json 文件不存在。不得不取消忽略该文件。【参考方案3】:

我遇到了同样的问题,在我的情况下,当我在调用 services.AddMediatR() 之后注册某个处理程序所需的依赖项是实际问题,在我开始注册我的依赖项之后,再注册 Mediator 一切正常。

我正在使用带有默认 DI 容器和 MediatR 6.0.0 的 dot net core 2.2。

【讨论】:

【参考方案4】:

对我来说,不幸的是,其他解决方案都没有工作,因为我已经注册了所有内容。我的解决方案是将以下行添加到我的 program.cs:

.UseDefaultServiceProvider(options => options.ValidateScopes = false);

所以CreateHostBuilder方法会改成:

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    
        webBuilder.UseStartup<Startup>();
    ).UseDefaultServiceProvider(options =>
    options.ValidateScopes = false); // needed for mediatr DI

其实这和“范围服务”有关,你可能会发现this的回答也有关系。

【讨论】:

【参考方案5】:

也许问题在于您的处理程序位于单独的程序集中,如果是,您需要在 Startup.cs 中注册该程序集名称。

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

“HandlersDomain”是存储所有处理程序的程序集的名称。

【讨论】:

【参考方案6】:

就我而言,我忘记在我的 Startup 中注册一些东西。就像我试图通过控制器实现的存储库一样。 Startup.cs 的方法 ConfigureServices 中缺少此功能:

 services.AddScoped<IDemoRepository, DemoRepository>();

【讨论】:

【参考方案7】:

我的结果是控制器中的一个坏名称属性。网址中已经有“客户”一词。将名称属性更改为“clientlist”并开始工作。

【讨论】:

【参考方案8】:

我今天遇到了这个问题,我的解决方案和注意点是,如果您要这样做:

services.AddMediatR(Assembly.GetExecutingAssembly());

请确保获取的程序集与您的处理程序相同。在我的例子中,处理程序位于不同的程序集(或您可能称之为的项目)中。

【讨论】:

【参考方案9】:

在我的例子中,堆栈跟踪显示了问题发生的原因:

System.InvalidOperationException: Error constructing handler for request of type    

MediatR.IRequestHandler`2[XXX.Core.Auth.Refresh.Request,XXXX.Core.Auth.Response]. 

Register your handlers with the container. See the samples in GitHub for examples.

---> MySqlConnector.MySqlException (0x80004005): Access denied for user 'sqluser'@'localhost' (using password: YES)

我的数据库没有设置连接字符串中指定的用户。通过将用户添加到数据库来修复。

【讨论】:

【参考方案10】:

我用这个方法解决了

services.AddMediatR(AppDomain.CurrentDomain.GetAssemblies());

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于ASP.NET Core MediatR 错误:向容器注册处理程序的主要内容,如果未能解决你的问题,请参考以下文章

Mediatr 无法解析 ASP.Net Core 中的 UserManager

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

ASP.NET Core MVC 入门到精通 - 3. 使用MediatR

如何为 ASP.NET Core 注册和使用 MediatR 管道处理程序?

带有 ASP.NET Core DI 的 MediatR

MediatR CQRS - 如何处理不存在的资源(asp.net core web api)