30

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

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

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

命令和命令处理程序类如下:

添加教育命令.cs

public class AddEducationCommand : IRequest<bool>
{
    [DataMember]
    public int UniversityId { get; set; }

    [DataMember]
    public int FacultyId { get; set; }

    [DataMember]
    public string Name { get; set; }
}

添加EducationCommandHandler.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 才能正常工作?提前致谢。

4

10 回答 10

41

我遇到了同样的问题。

问题是这一行代码

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

处理所有 MediatR IRequest 和 IRequestHandlers。

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

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

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

然后问题解决了。

于 2018-08-02T15:53:37.467 回答
13

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

我是怎么得出这个结论的?

为了得到原始异常,我打开了事件查看器应用程序,它默认存在于 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
于 2020-06-12T07:35:43.407 回答
6

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

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

于 2019-04-26T00:48:08.583 回答
5

对我来说,不幸的是,其他解决方案都不起作用,因为我已经注册了所有内容。我的解决方案是在我的 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

实际上这与“范围服务”有关,您可能会发现这个答案也相关。

于 2020-12-14T07:26:48.817 回答
1

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

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

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

于 2021-05-01T09:59:20.990 回答
0

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

 services.AddScoped<IDemoRepository, DemoRepository>();
于 2020-06-13T14:55:07.500 回答
0

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

于 2021-06-02T19:48:07.427 回答
0

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

services.AddMediatR(Assembly.GetExecutingAssembly());

请确保获得的程序集与您的处理程序相同。就我而言,处理程序位于不同的程序集(或您可以称之为项目)中。

于 2021-06-23T16:13:26.680 回答
0

就我而言,堆栈跟踪显示了问题发生的原因:

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)

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

于 2021-07-19T17:03:52.610 回答
0

我用这个替代解决了

services.AddMediatR(AppDomain.CurrentDomain.GetAssemblies());
于 2022-01-28T07:26:56.050 回答