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 > 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