jamesmh / coravel

Near-zero config .NET library that makes advanced application features like Task Scheduling, Caching, Queuing, Event Broadcasting, and more a breeze!
https://docs.coravel.net/Installation/
MIT License
3.92k stars 257 forks source link

Using Dependency Injection with ScheduleAsync #362

Closed serajoddin-aliabadi closed 9 months ago

serajoddin-aliabadi commented 9 months ago

There is no example of using Dependency Injection in ScheduleAsync method within docs. I do it this way:

app.Services.UseScheduler(scheduler =>
{
    scheduler
        .ScheduleAsync(async () =>
        {
            await using var scope = app.Services.CreateAsyncScope();

            var job = scope.ServiceProvider.GetService<Coravel.Invocable.IInvocable>();

            await job.Invoke();
        })
        .Weekly()
        .RunOnceAtStart();
});

Is it right? or any other better way?

jamesmh commented 9 months ago

Yes, that's basically how you would do this 👍.

Using invocables is the recommended way to schedule tasks, but ultimately it's your choice 👍

jozefRudy commented 2 months ago

Yes, that's basically how you would do this 👍.

Using invocables is the recommended way to schedule tasks, but ultimately it's your choice 👍

Now, is it idiomatic to use Invocables, in a way where invoke returns a task (and hence is async)?

I mean, it's slightly confusing that there is also separate scheduleAsync method (which is harder to use with DI), alongside using invocable interface which has Task Invoke method.

Are these 2 equivalent in terms of how those operations are scheduled in thread pool, with a following example

public class Invocable : IInvocable {

    public async Task Invoke()
    {
        await Task.Delay(1);
    }
}

s.Schedule<Invocable>().Daily()

@jamesmh

jamesmh commented 2 months ago

They behave the same other than differences between using a class vs function. Ex. your function could have capture a variable from it's outer scope, etc.

But other wise they are scheduled the same on the thread pool, etc.

Using the function approach is probably best for simple things. Otherwise, invocables are the best option.