ASP.net Core API FluentScheduler 定时任务 依赖注入 服务接口

本文探讨了在ASP.NET Core API中使用FluentScheduler进行后台任务调度时如何实现依赖注入。通过实例展示了如何配置Autofac容器并设置JobFactory来解决构造函数注入问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FluentScheduler dependency injection in constructor

原文链接:https://www.thetopsites.net/article/50617160.shtml

I am experimenting with FluentScheduler for some background tasks in ASP.net Core API.

The job should send push notifications every day at a particular time interval based on few criteria. I had gone through the document and implemented a test functionality to print some output in the console window. It worked as expected with predicted time interval.

But the actual job I am going to do with that involves database context which provides necessary information to perform the criteria to send out the notifications.

My problem is I am unable to use constructor with parameter in MyJob class which is throwing missing method exception

PS: As per this article from Scott Hanselman, FluentScheduler seems to be quite famous but I could not get any help from online communities. But obviously, it's quite easy to grasp.

public class MyJob : IJob
{
    private ApplicationDbContext _context;

    public MyJob(ApplicationDbContext context)
    {
        _context = context;
    }

    public void Execute()
    {
        Console.WriteLine("Executed");
        SendNotificationAsync();
    }

    private async Task SendNotificationAsync()
    {
        var overdues = _context.Borrow.Join(
            _context.ApplicationUser,
            b => b.ApplicationUserId,
            a => a.Id,
            (a, b) => new { a, b })
            .Where(z => (z.a.ReturnedDate == null) && (z.a.BorrowApproval == 1))
            .Where(z => z.a.ReturnDate.Date == new DateTime().Date.AddDays(1).Date)
            .Select(z => new { z.a.ApplicationUserId, z.a.Book.ShortTitle, z.a.BorrowedDate, z.b.Token })
            .ToList();

        Console.WriteLine("Acknowledged");

        foreach (var r in overdues)
        {
            string message = "You are running late! The book '" + r.ShortTitle + "' borrowed on '" + r.BorrowedDate + "' due tomorrow.";
            Console.WriteLine(message);
            await new PushNotificationService().sendAsync(r.Token, "Due Tomorrow!", message);
        }
    }
}

From the source code for IJob, it looks like your class that implements IJob needs to have a parameterless default constructor. Since FluentScheduler also supports lambdas, it may be easier to have your dependency injection library create your object, then call the Execute method like so:

var myJob = new MyJob(new ApplicationDbContext());
Schedule(() => myJob.Execute()).ToRunEvery(1).Days().At(21, 15);

Or call the constructor yourself:

// Schedule a job using a factory method and pass parameters to the constructor.
Schedule(() => new MyJob(new ApplicationDbContext())).ToRunNow().AndEvery(2).Seconds();

FluentScheduler dependency injection in constructor, Net and much more using FluentScheduler I'm trying to use a Core 2.0+ ? I want to use my services and resolve them dependencies. You can use constructor injection for your jobs and get that seamless ASP.NET Core  As you said, your job is registered with a scoped lifetime 'Web API Request'. This means that a instance of a dependency is created by the container per request and it is disposed when the request ends. Your job is running inside FluentScheduler and is not linked with any request.

Note - In the documentation it says not to use IJobFactory because it is going to be deprecated soon, but it is working for me in Production for past 3,4 months - https://github.com/fluentscheduler/FluentScheduler/issues/71

I am using Autofac and Fluent Scheduler in a Windows Console Application which uses TopShelf to run it as a Windows Service.

To use Dependency Injection in FluentScheduler you have to setup a Job Factory to resolve the dependencies.

So first setup a JobFactory by implementing IJobFactory

Like this -

public class MyJobFactory : IJobFactory
{
    public IJob GetJobInstance<T>() where T : IJob
    {
        return MyContainer.GetJobInstance<T>();
    }
}

Now in the Job Factory because I'm using Autofac I am setting up a Container which has 2 methods

1 - ConfigureDependencies() - Which is only called once to setup the Container:

2 - GetJobInstance() - Which is called by the MyJobFactory to resolve t a Job instance

public class MyContainer
{
    public static IContainer Container { get; set; }

    public static void ConfigureDependencies()
    {
        var builder = new ContainerBuilder();

        // Jobs
        builder.RegisterType<MyJob>().As<MyJob>();

        // DB Contexts

        // Others

        Container = builder.Build();
    }


    public static IJob GetJobInstance<T>() where T : IJob
    {
        return Container.Resolve<T>();
    }
}

Then when you Start you application/service, it will look something like this.

public void Start()
{
    // Configure Dependency Injection
    MyContainer.ConfigureDependencies();

    // Setup the Fluent Scheduler - 
    JobManager.JobFactory = new MyJobFactory();

    JobManager.UseUtcTime();

    JobManager.Initialize(new MyJobRegistry());     
}

Then I've created a Job by adding 2 constructors -

1 - Parameter-less

2 - The constructor with Injected Objects

e.g.

public class MyJob : IJob
{
    public static string JobName = "MyJob";

    private readonly ICompaniesProvider _companiesProvider;

    // parameter-less constructor
    public MyJob() { }

    // injecting HERE
    public MyJob(ICompaniesProvider companiesProvider)
    {
        _companiesProvider = companiesProvider;

    }

    public void Execute()
    {



    }
}

EDIT

Because of deprecated issue of IJobFactory, you could just call the Container Directly and get a Job Instance before adding it to the JobManager

public void Start()
{
    // Configure Dependency Injection
    MyContainer.ConfigureDependencies();

    JobManager.UseUtcTime();
    JobManager.Start();

    var myJob = MyContainer.GetJobInstance<MyJob>();

    Action<Schedule> schedule = s => s.ToRunEvery(1).Hours().At(0);

    JobManager.AddJob(myJob, schedule);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdn_aspnet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值