.NET Core console app Mediatr command handler doesn't get called

user3646017 picture user3646017 · Feb 25, 2019 · Viewed 8.6k times · Source

I'm facing a problem that Mediatr command handler is not called. I have the following solution structure.

Project.sln -> Application layer (.NET standard class library) -> Jobs (.NET standard class library) -> Job Server (.NET Core console app)

The idea is that Job Server uses scheduler (Quartz.NET) to execute Jobs. The actual business logic is in Application layer. Application layer uses CQRS pattern which is wired using Mediatr. I'm using Microsoft dependency injection libraries.

Job Server Main method (with DI code):

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");
    }
}

Code from Quartz.net job:

[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 command:

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

After debugging I've concluded that code stops executing after initializing ProcessAdSectionsRssCommand class (if I create an empty constructor, it will be executed). Unfortunately, I haven't got any actual error messages, I think some sort of exception might be swallowed. Handler class as far as I can tell never gets initialized.

  • Mediatr version: 6.0.0
  • .NET code SDK version: 2.2
  • Microsoft DI version (Microsoft.Extensions.DependencyInjection): 2.2.0

I suspect it's some sort of DI + Mediatr related issue. Anyone has any ideas? Thanks.

Answer