Asp.net core Asp.net核心Quartz作业调用控制器方法,但上下文

Asp.net core Asp.net核心Quartz作业调用控制器方法,但上下文,asp.net-core,dependency-injection,blazor,quartz.net,Asp.net Core,Dependency Injection,Blazor,Quartz.net,我有一个aspnetcore服务器(为Blazor wasm应用程序提供服务),它有一个Quartz计划的作业正在运行。当作业触发时,它正在我的服务器的一个控制器上调用一个方法 如果我在我的控制器上正常调用此方法(例如通过web API调用),它工作正常 当我从Quartz IJob调用该方法时,控制器中使用的DbContext似乎已被释放。 我尝试过以正常的方式将控制器注入到作业中,也尝试过通过IServiceProvider,两者都有相同的结果 控制器: public class Notif

我有一个aspnetcore服务器(为Blazor wasm应用程序提供服务),它有一个Quartz计划的作业正在运行。当作业触发时,它正在我的服务器的一个控制器上调用一个方法

如果我在我的控制器上正常调用此方法(例如通过web API调用),它工作正常

当我从Quartz IJob调用该方法时,控制器中使用的DbContext似乎已被释放。 我尝试过以正常的方式将控制器注入到作业中,也尝试过通过IServiceProvider,两者都有相同的结果

控制器:

public class NotificationController : ControllerBase
{
    private readonly ApplicationDbContext context;
    
    public NotificationService(ApplicationDbContext context)
    {
        this.context = context;
    }

    public async Task MyMethod()
    {
        await context.SaveChangesAsync(); //This is where it fails when Quartz calls it, seems context is not populated
    }
}
我的工作(IServiceProvider尝试):

My Startup.cs(ConfigureServices中的相关行):

public void配置服务(IServiceCollection服务)
{
services.AddSignalR();
services.AddControllersWithViews();
services.AddMvcCore().addControllerAsservices();
services.AddRazorPages();
services.AddQuartz(q=>
{
q、 UseMicrosoftDependencyInjectionScopedJobFactory();//我还尝试将options.CreateScope传递给此方法,但没有区别
q、 AddJobAndTrigger(配置);
});
services.AddQuartzHostedService(q=>q.WaitForJobsToComplete=true);
services.AddDbContext(选项=>
options.UseSqlServer(configuration.GetConnectionString(“DefaultConnection”));
}

当VS尝试执行context.saveChangesSync()时,不会在VS中引发任何异常,但是,在未命中断点之后会直接出现一个断点,但是,当我在调试时检查上下文的详细信息时,它似乎没有正确填充

如何从IJob中使用控制器,并确保不处理控制器的依赖关系

如何从IJob中使用控制器

请勿在作业中使用控制器

将所需功能移动/提取/重构到服务抽象中

//Service abstraction
public interface INotificationService {
    Task MyMethod();
}

public class NotificationService : INotificationService {
    private readonly ApplicationDbContext context;

    public NotificationService(ApplicationDbContext context) {
        this.context = context;
    }

    public async Task MyMethod() {
        await context.SaveChangesAsync();
    }
}
并使作业和控制器依赖于服务来调用所需的功能

public class NotificationController : ControllerBase {
    private readonly INotificationService service;
    
    public NotificationController (INotificationService service ) {
        this.service = service ;
    }    

    public async Task<IActionResult> MyMethod() {
        await service.MyMethod(); 
        return Ok();
    }
}

public class ReminderJob : IJob {
    private readonly INotificationService service;

    public ReminderJob(INotificationService service) {
        this.service = service;
    }

    public Task Execute(IJobExecutionContext jobcontext) {
        return service.MyMethod();
    }
}
公共类NotificationController:ControllerBase{
私有只读INotificationService服务;
公共通知控制器(INotificationService){
服务=服务;
}    
公共异步任务MyMethod(){
wait service.MyMethod();
返回Ok();
}
}
公共类提醒器作业:IJob{
私有只读INotificationService服务;
公共提醒作业(INotificationService){
服务=服务;
}
公共任务执行(iJobeExecutionContext作业上下文){
return service.MyMethod();
}
}
当然,在DI容器中注册所有必要的服务

//...

services.AddScoped<INotificationService, NotificationService>();

//...
/。。。
services.addScope();
//...
//Service abstraction
public interface INotificationService {
    Task MyMethod();
}

public class NotificationService : INotificationService {
    private readonly ApplicationDbContext context;

    public NotificationService(ApplicationDbContext context) {
        this.context = context;
    }

    public async Task MyMethod() {
        await context.SaveChangesAsync();
    }
}
public class NotificationController : ControllerBase {
    private readonly INotificationService service;
    
    public NotificationController (INotificationService service ) {
        this.service = service ;
    }    

    public async Task<IActionResult> MyMethod() {
        await service.MyMethod(); 
        return Ok();
    }
}

public class ReminderJob : IJob {
    private readonly INotificationService service;

    public ReminderJob(INotificationService service) {
        this.service = service;
    }

    public Task Execute(IJobExecutionContext jobcontext) {
        return service.MyMethod();
    }
}
//...

services.AddScoped<INotificationService, NotificationService>();

//...