gpt4 book ai didi

asp.net-core - 如何集成需要在其中注入(inject) "scoped"服务的 Quartz.Net 作业(ASP.NET Core 2.0)?

转载 作者:行者123 更新时间:2023-12-04 02:50:49 25 4
gpt4 key购买 nike

我正在尝试在 my own answer 之后创建一些 Quartz.Net 作业来自 this question .但是,如果作业相当复杂并且需要“范围内的”( services.AddScoped<.., ...> ) 服务,则该示例不起作用,因为作业是作为单例创建的。

如果我将它们更改为范围,则 serviceProvider 不包含我需要的服务。我已经设法使用以下代码使其工作:

启动.cs

/// <summary>
/// service provider to be used by qiaryz job factory which cannot use its default provider
/// since child services are scoped and the jobs are singleton
/// </summary>
public static IServiceProvider QuartzScopedProvider { get; private set; }

private void ConfigureQuartz(IServiceCollection services, params Type[] jobs)
{
services.AddSingleton<IJobFactory, QuartzJobFactory>();
services.Add(jobs.Select(jobType => new ServiceDescriptor(jobType, jobType, ServiceLifetime.Singleton)));

QuartzScopedProvider = services.BuildServiceProvider();

services.AddSingleton(provider =>
{
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler().Result;
scheduler.JobFactory = provider.GetService<IJobFactory>();
scheduler.Start();
return scheduler;
});
}

/// <summary>
/// configures quartz services
/// </summary>
/// <param name="services"></param>
protected virtual void ConfigureJobsIoc(IServiceCollection services)
{
// all custom services are already defined at this point

ConfigureQuartz(services, typeof(ComplexJob));
}

/// <summary>
/// configures and starts async jobs (Quartz)
/// </summary>
/// <param name="app"></param>
/// <param name="lifetime"></param>
protected virtual void StartJobs(IApplicationBuilder app, IApplicationLifetime lifetime)
{
var scheduler = app.ApplicationServices.GetService<IScheduler>();

QuartzServicesUtilities.StartJob<ComplexJob>(scheduler, TimeSpan.FromMinutes(60));

lifetime.ApplicationStarted.Register(() => scheduler.Start());
lifetime.ApplicationStopping.Register(() => scheduler.Shutdown(waitForJobsToComplete: true));
}

QuartzJobFactory.cs

作业工厂不使用注入(inject)的服务提供者,而是在Startup.cs中显式构建的服务提供者

public class QuartzJobFactory : IJobFactory
{
private readonly IServiceProvider _serviceProvider;

/// <inheritdoc/>
public QuartzJobFactory()
{
// _serviceProvider = serviceProvider;
_serviceProvider = Startup.QuartzScopedProvider;
}

/// <inheritdoc/>
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
var jobDetail = bundle.JobDetail;

// this fails with injected service provider:
// 1: cannot inject scoped services in singleton service
// 2: if jobs are scoped, the provider cannot solve the injected services
var job = (IJob)_serviceProvider.GetService(jobDetail.JobType);
return job;
}

/// <inheritdoc/>
public void ReturnJob(IJob job) { }
}

我想知道这是否是处理 ASP.NET Core 2.0 中 Quartz 作业的好方法,因为它看起来更像是 hack 而不是真正的解决方案。

问题:如何集成需要注入(inject)“作用域”服务的 Quartz.Net 作业 (ASP.NET Core 2.0)?

最佳答案

要从 IServiceProvider 中恢复作用域服务,请尝试

    using (var scope = _serviceProvider.CreateScope())
{
var job = (IJob)scope.ServiceProvider.GetService(jobDetail.JobType);
}

关于asp.net-core - 如何集成需要在其中注入(inject) "scoped"服务的 Quartz.Net 作业(ASP.NET Core 2.0)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55170110/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com