首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >具有多级DI的Quartz.Net作业

具有多级DI的Quartz.Net作业
EN

Stack Overflow用户
提问于 2019-06-24 07:52:40
回答 1查看 6.1K关注 0票数 1

我有一个可以工作的JobFactory : IJobFactory。其中一个依赖项本身依赖于HttpClient,但这似乎不起作用。

例如。

代码语言:javascript
复制
services.AddHttpClient<Dependency>("dependency");
services.AddSingleton(typeof(Dependency));

using (var serviceProvider = services.BuildServiceProvider())
{
  var schedulerFactory = new StdSchedulerFactory();
  var scheduler = await schedulerFactory.GetScheduler();
  scheduler.JobFactory = new JobFactory(serviceProvider);
  await scheduler.Start();

  var job = JobBuilder.Create<Job1>()
                .WithIdentity("job1")
                .Build();
  var trigger = TriggerBuilder.Create()
                .WithIdentity("trigger1")
                .StartNow()
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(1)
                    .RepeatForever())
                .Build();
  await scheduler.ScheduleJob(job, trigger);
}

依赖构造函数为

代码语言:javascript
复制
public Dependency(HttpClient httpClient)
{
  // <snipped>
}

而作业构造器是

代码语言:javascript
复制
public Job1(Dependency dependency)
{
  // <snipped>
}

当我尝试运行它时,我被告知该作业抛出了一个未处理的异常。通过我的JobFactory进行调试,我发现httpClient根本没有被注入。不是应该由.AddHttpClient来处理吗?它不能工作是因为DI的多层次吗?有没有可能用另一种方式?

EN

回答 1

Stack Overflow用户

发布于 2019-06-24 08:51:38

这段代码进行重构的时机已经成熟。

将调度器放在IHostedService中,让它来处理调度器的启动。

代码语言:javascript
复制
public interface IHostedService {
    //
    // Summary:
    //     Triggered when the application host is ready to start the service.
    Task StartAsync(CancellationToken cancellationToken);
    //
    // Summary:
    //     Triggered when the application host is performing a graceful shutdown.
    Task StopAsync(CancellationToken cancellationToken);
}

public class SchedulerService : IHostedService {
    readonly IJobFactory jobFactory;
    readonly ISchedulerFactory schedulerFactory
    IScheduler  scheduler;

    public SchedulerService(IJobFactory jobFactory, ISchedulerFactory schedulerFactory) {
        this.jobFactory = jobFactory;
        this.schedulerFactory = schedulerFactory;
    }

    public async Task StartAsync(CancellationToken cancellationToken) {
        scheduler = await schedulerFactory.GetScheduler();
        scheduler.JobFactory = jobFactory;

        IJobDetail job = JobBuilder.Create<Job1>()
            .WithIdentity("job1")
            .Build();

        ITrigger  trigger = TriggerBuilder.Create()
            .WithIdentity("trigger1")
            .StartNow()
            .WithSimpleSchedule(x => x.WithIntervalInSeconds(1)
                .RepeatForever())
            .Build();

        await scheduler.ScheduleJob(job, trigger);

        await scheduler.Start(cancellationToken);
    }

    public Task StopAsync(CancellationToken cancellationToken) {
        return scheduler.Shutdown(cancellationToken);
    }
}

现在,通过将所有类型添加到服务集合中,可以在启动时干净地完成配置

代码语言:javascript
复制
class Program {
    static async Task Main(string[] args) {

        var services = new ServiceCollection();

        //...

        services.AddHttpClient<IDependency, Dependency>();
        services.AddScoped<Job1>();
        services.AddTransient<ISchedulerFactory, StdSchedulerFactory>();
        services.AddTransient<IJobFactory>(serviceProvider => new JobFactory(serviceProvider)); 
        services.AddTransient<IHostedService, SchedulerService>();

        //...

        IServiceProvider serviceProvider = services.BuildServiceProvider();

        var service = serviceProvider.GetRequiredService<IHostedService>(); 
        await service.StartAsync();

        Console.ReadKey();

    }
}

因此,现在服务将管理启动,并根据需要注入所有必要的依赖项。

包括类型化的客户端Dependency类,假设如下

代码语言:javascript
复制
public class Dependency : IDependency {

    public Dependency(HttpClient httpClient) {
      // <snipped>
    }
}

public class Job1: IJob {
    public Job1(IDependency dependency) {
      // <snipped>
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56728515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档