.NET Core控制台应用程序Mediatr命令处理程序未被调用。

5
我是一名有用的助手,可以为您翻译文本。以下是需要翻译的内容:

我遇到了一个问题,Mediatr命令处理程序没有被调用。 我有以下解决方案结构。

Project.sln -> 应用层(.NET标准类库) -> 作业(.NET标准类库) -> 作业服务器(.NET Core控制台应用程序)

想法是Job Server使用调度程序(Quartz.NET)执行作业。实际的业务逻辑在应用层中。应用层使用已连接的Mediatr CQRS模式。我正在使用Microsoft依赖项注入库。

作业服务器Main方法(带有DI代码):

public class Program
{
    static ManualResetEvent _quitEvent = new ManualResetEvent(false);

    static void Main(string[] args)
    {
        Console.WriteLine("Job Server started");

        //DI setup
        var serviceProvider = new ServiceCollection()
            .AddQuartz()
            .AddTransient<InitializeJobServer>()
            .AddTransient<ProcessAdRssFeedsJob>()
            .AddScoped<IConfigService, ConfigService>()
            .AddScoped<IRssService, RssService>()
            .AddScoped<IBaseService, BaseService>()
            .AddMediatR(typeof(ProcessAdSectionsRssCommand).GetType().Assembly)
            .AddDbContext<MyDbContext>(options =>
                options.UseNpgsql("xxx"))
            .AddMemoryCache()
            .BuildServiceProvider();

        Console.CancelKeyPress += (sender, eArgs) => {
            _quitEvent.Set();
            eArgs.Cancel = true;
        };

        Task.Run(async () =>
        {
            await serviceProvider.GetService<InitializeJobServer>().Start();
        });

        _quitEvent.WaitOne();
        Console.WriteLine("Job Server ended");
    }
}

来自Quartz.net作业的代码:

[DisallowConcurrentExecution]
public class ProcessAdRssFeedsJob : IJob
{
    private readonly IMediator _mediator;

    public ProcessAdRssFeedsJob(IMediator mediator)
    {
        _mediator = mediator;
    }

    public Task Execute(IJobExecutionContext context)
    {
        try
        {
            _mediator.Send(new ProcessAdSectionsRssCommand());               
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
        return null;
    }
}

Mediatr 命令:

public class ProcessAdSectionsRssCommand : IRequest<bool>
{

    public class Handler : IRequestHandler<ProcessAdSectionsRssCommand, bool>
    {
        private readonly MyDbContext _context;
        private readonly IRssService _rssService;
        private readonly IConfigService _configService;

        public Handler(
            MyDbContext context,
            IRssService rssService,
            IConfigService configService)
        {
            _context = context;
            _rssService = rssService;
            _configService = configService;
        }

        public async Task<bool> Handle(ProcessAdSectionsRssCommand request, CancellationToken cancellationToken)
        {
            var config = await _configService.GetAllConfigs();

            var r0 = await _rssService.GetAdSectionRssUrls();
            // etc.
            return true;
        }
    }
}

调试后,我得出结论:在初始化 ProcessAdSectionsRssCommand 类之后代码停止执行(如果我创建一个空的构造函数,则它将被执行)。不幸的是,我没有得到任何实际的错误消息,我认为某种异常可能已经被忽略了。据我所知,Handler 类从未被初始化。

  • Mediatr 版本:6.0.0
  • .NET 代码 SDK 版本:2.2
  • Microsoft DI 版本(Microsoft.Extensions.DependencyInjection):2.2.0

我怀疑这是一些 DI + Mediatr 相关的问题。有人有什么想法吗? 谢谢。


@MickaëlDerriey 谢谢您的建议!在应用了建议后,我遇到了异常 System.InvalidOperationException: Handler was not found for request of type MediatR.IRequestHandler 2[xxx.Application.Rss.Commands.ProcessAdSectionsRss.ProcessAdSectionsRssCommand,System.Boolean]. Register your handlers with the container. See the samples in GitHub for examples. 我猜问题仍然存在 - 如何设置依赖注入以使控制台应用程序正常工作?请注意,在 ASP.NET Core 项目中,此逻辑是有效的。另外,我尝试删除处理程序的所有依赖项。 - user3646017
我尝试将处理程序类移动到请求类之外。MyDbContext是正确的名称(之前是复制/粘贴问题),已注册。我还从处理程序的构造函数中删除了所有依赖项。我还尝试在 DI 中注册请求/处理程序类。到目前为止,问题仍然存在。 - user3646017
如果您调试应用程序并分析异常,InnerException 可能会提供有关出现问题的更多详细信息。 - Mickaël Derriey
也许处理程序的依赖项之一 - MyDbContextConfigServiceBaseService - 其中有依赖项未在容器中注册? - Mickaël Derriey
4
好的,我终于成功解决了这个问题。原来需要在“ServiceCollection”中明确注册处理程序。你可以在这个提交记录中看到我是如何做到的。@MickaëlDerriey感谢你的帮助! - user3646017
显示剩余3条评论
1个回答

1

我认为你调用 Send() 方法的时候漏掉了一个 await 关键字。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接