.NET Core Worker service host and Coravel Scheduler

2.4k Views Asked by At

I have created a worker service to schedule a task using Coravel is a .NET Standard library and it is working as expected if I don't use the extra parameter with the string. I want to host the same as a windows service.

Program.cs

        static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder();
        BuildConfig(builder);

        Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(builder.Build())
            .Enrich.FromLogContext()
            .WriteTo.Console()
            .CreateLogger();

        var host = Host.CreateDefaultBuilder()               
            .ConfigureServices((context, services) =>
            {
                services.AddScheduler();
                services.AddTransient<CoravelService>();
            })
            .UseSerilog()
            .Build();

        host.Services.UseScheduler(scheduler =>
        {
            var jobSchedule = scheduler.Schedule<CoravelService>();
            jobSchedule.EverySecond();
        });
        host.Run();
    }

CoravelService.cs

    public CoravelService(ILogger<CoravelService> log, IConfiguration configuration)
    {
        _log = log ??
            throw new ArgumentNullException(nameof(log));
        _configuration = configuration ??
            throw new ArgumentNullException(nameof(configuration));

    }

    public Task Invoke()
    {
        var testGuid = "test";
        _log.LogError(testGuid.ToString());

        return Task.FromResult(true);
    }

And its works perfectly, but problem begins when i want to have one more extra parameter in Coravel Service.

CoravelService.cs

    public CoravelService(ILogger<CoravelService> log, IConfiguration configuration, string someArgument)
    {
        _log = log ??
            throw new ArgumentNullException(nameof(log));
        _configuration = configuration ??
            throw new ArgumentNullException(nameof(configuration));
        _someArgument = someArgument;

    }

    public Task Invoke()
    {
        _log.LogError(_someArgument);

        return Task.FromResult(true);
    }

In this situantion constructor is not initializing, i think the reason of this situation is that i should somewhere pass this string, but i dont know where and how.

2

There are 2 best solutions below

0
Jmeijer On

I got this working by implementing IInvocableWithPayload<T> on my invocable class and using scheduler.ScheduleWithParams() to add jobs to the schedule.

Using the example from the question it would look like this:

Program.cs relevant part

host.Services.UseScheduler(scheduler =>
{
    var jobSchedule = scheduler.ScheduleWithParams<CoravelService>("test");
    jobSchedule.EverySecond();
});
host.Run();

CoravelService.cs

public class CoravelService : IInvocable, IInvocableWithPayload<string>
{
    public ILogger _log { get; set; }
    public IConfiguration _configuration { get; set; }
    public string Payload { get; set; }

    public CoravelService(ILogger<CoravelService> log, IConfiguration configuration, string payload)
    {
        _log = log ??
            throw new ArgumentNullException(nameof(log));
        _configuration = configuration ??
            throw new ArgumentNullException(nameof(configuration));
        Payload = payload;
    }

    public Task Invoke()
    {
        _log.LogError(Payload);

        return Task.FromResult(true);
    }
}
0
Alan B On

There's a basic solution illustrating how to host the Coravel scheduler as a Windows service using BackgroundService in this GitHub repo.