C# 构造函数中的FluentScheduler依赖项注入

C# 构造函数中的FluentScheduler依赖项注入,c#,asp.net-core,scheduled-tasks,fluentscheduler,C#,Asp.net Core,Scheduled Tasks,Fluentscheduler,我正在ASP.net核心API中的一些后台任务中试用FluentScheduler 作业应根据几个条件,每天以特定的时间间隔发送推送通知。我已经阅读了文档并实现了一个测试功能来在控制台窗口中打印一些输出。它按照预期的时间间隔工作 但我要做的实际工作涉及数据库上下文,它提供必要的信息来执行发送通知的标准 我的问题是我无法在MyJob类中使用带参数的构造函数,该类引发缺少的方法异常 PS:根据Scott Hanselman的这篇文章,FluentScheduler似乎很有名,但我无法从在线社区获得任

我正在ASP.net核心API中的一些后台任务中试用FluentScheduler

作业应根据几个条件,每天以特定的时间间隔发送推送通知。我已经阅读了文档并实现了一个测试功能来在控制台窗口中打印一些输出。它按照预期的时间间隔工作

但我要做的实际工作涉及数据库上下文,它提供必要的信息来执行发送通知的标准

我的问题是我无法在
MyJob
类中使用带参数的构造函数,该类引发缺少的方法异常

PS:根据Scott Hanselman的这篇文章,FluentScheduler似乎很有名,但我无法从在线社区获得任何帮助。但很明显,这很容易理解

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);
        }
    }
}
从for IJob的示例来看,实现IJob的类似乎需要一个无参数的默认构造函数。由于FluentScheduler也是如此,让依赖项注入库创建对象,然后调用
Execute
方法可能更容易,如下所示:

var myJob = new MyJob(new ApplicationDbContext());
Schedule(() => myJob.Execute()).ToRunEvery(1).Days().At(21, 15);
或者自己调用构造函数:

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

注意-文档中说不要使用IJobFactory,因为它很快就会被弃用,但它在过去3,4个月的生产中对我有效-

我正在Windows控制台应用程序中使用
Autofac
Fluent调度程序
,该应用程序使用
TopShelf
将其作为Windows服务运行

要在FluentScheduler中使用依赖项注入,必须设置作业工厂来解析依赖项

因此,首先通过实现
IJobFactory

像这样-

public class MyJobFactory : IJobFactory
{
    public IJob GetJobInstance<T>() where T : IJob
    {
        return MyContainer.GetJobInstance<T>();
    }
}
然后,当您启动应用程序/服务时,它将如下所示

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

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

    JobManager.UseUtcTime();

    JobManager.Initialize(new MyJobRegistry());     
}
然后我通过添加2个构造函数创建了一个作业-

1-无参数

2-具有注入对象的构造函数

e、 g

编辑

由于不推荐使用的
IJobFactory
,您可以直接调用容器并在将其添加到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);
}
public void Start()
{
//配置依赖项注入
MyContainer.ConfigureDependencies();
JobManager.UseUtcTime();
JobManager.Start();
var myJob=MyContainer.GetJobInstance();
行动计划=s=>s.ToRunEvery(1).Hours().At(0);
JobManager.AddJob(myJob,schedule);
}

我在这里发布了类似的答案-


我使用了注入注册表构造函数的应用程序服务作用域,并使用此作用域获取作业类的execute方法中的对象。

new ApplicationDbContext()不应该是已从ConfigureServices实例化的对象吗?它只是一个占位符,表示您正在获取的
ApplicationDbContext
new MyJob(new ApplicationDbContext())不被接受。与no mssing method error相同的错误您当前如何获取
ApplicationDbContext
的实例?我无法获取。这就是问题所在。不知何故,我可以将已经运行的DbContext实例注入到计划中,这样我就能够完成我的任务。
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()
    {



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