如何整合需要“范围"管理的Quartz.Net作业.服务注入其中(ASP.NET Core 2.0)? [英] How to integrate Quartz.Net jobs that require "scoped" services injected in them (ASP.NET Core 2.0)?

查看:84
本文介绍了如何整合需要“范围"管理的Quartz.Net作业.服务注入其中(ASP.NET Core 2.0)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据services.AddScoped<.., ...>)服务,则该示例将无法正常工作,因为作业是作为单例创建的.

I am trying to create some Quartz.Net jobs following my own answer from this question. However, if the job is fairly complex and required "scoped" (services.AddScoped<.., ...>) services, the example does not work because jobs are created as singletons.

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

If I change them to be scoped, the serviceProvider does not contain the services I need. I have managed to make it work using the following code:

/// <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

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

QuartzJobFactory.cs

The job factory does not use the injected service provider, but the one explicitly constructed in 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作业的好方法,因为它看起来更像是黑客,而不是真正的解决方案.

I am wondering if this is a good way to deal with Quartz jobs in ASP.NET Core 2.0 because it looks more like a hack than a real solution.

问题::如何集成需要向其中注入范围"服务(ASP.NET Core 2.0)的Quartz.Net作业?

Question: How to integrate Quartz.Net jobs that require "scoped" services injected in them (ASP.NET Core 2.0)?

推荐答案

要从IServiceProvider抢救作用域服务,请尝试

For resoving scoped service from IServiceProvider, try

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

这篇关于如何整合需要“范围"管理的Quartz.Net作业.服务注入其中(ASP.NET Core 2.0)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆