Используйте Microsoft DependencyInjection в проблемах области TopShelf и Quartz - PullRequest
0 голосов
/ 21 октября 2018

Я использую TopShelf и Quartz для планирования некоторых работ в качестве службы Windows.Для внедрения зависимостей я использую пакет Microsoft.Extensions.DependencyInjection.Моя проблема связана с функциональностью Scope, я хочу при настройке службы в жизненном цикле области (например, ISampleService), за раунд выполнения задания, избавиться от сервисов жизненного цикла области и снова создать экземпляр следующего раунда, но жизненный цикл области ведет себя как жизненный цикл singleton,Ниже приведен мой код:

Зависимости:

using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Topshelf;

Основной метод:

static void Main(string[] args)
{
    var provider = RegisterServices();

    HostFactory.Run(cfg =>
    {
        cfg.Service<SampleTask>(s =>
        {
            s.ConstructUsing(() => provider.GetService<SampleTask>());
            s.WhenStarted(async f => await f.Start(provider));
            s.WhenStopped(f => f.Stop());
        });

        cfg.RunAsLocalSystem();
        cfg.SetDescription("description");
        cfg.SetDisplayName("name");
        cfg.SetServiceName("service");
    });
}

Метод RegisterServices

public static ServiceProvider RegisterServices()
{
    IServiceCollection services = new ServiceCollection();

    services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();

    services.AddTransient<SampleTask>();
    services.AddTransient<IJob, SampleJob>();
    services.AddScoped<ISampleService, SampleService>

    var provider = services.BuildServiceProvider();

    return provider;
}

JobFactory:

public class JobFactory : IJobFactory
{
    protected readonly IServiceProvider Container;

    public JobFactory(IServiceProvider container)
    {
        Container = container;
    }

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        return Container.GetService(bundle.JobDetail.JobType) as IJob;
    }

    public void ReturnJob(IJob job)
    {
        (job as IDisposable)?.Dispose();
    }
}

Задание:

public class SampleTask
{
    private readonly ISchedulerFactory _schedulerFactory;

    public SampleTask(ISchedulerFactory schedulerFactory)
    {
        _schedulerFactory = schedulerFactory;
    }

    public async Task Start(ServiceProvider provider)
    {
        var scheduler = await _schedulerFactory.GetScheduler();
        scheduler.JobFactory = new JobFactory(provider);

        var job = JobBuilder.Create<IJob>().Build();

        var trigger = TriggerBuilder.Create()
            .WithIdentity("Sample1", "SampleGroup")
            .WithSimpleSchedule(x => x
                .WithIntervalInMinutes(10)
                .RepeatForever())
            .StartNow()
            .Build();

        await scheduler.ScheduleJob(job, trigger);

        await scheduler.Start();
    }

    public bool Stop()
    {
        return true;
    }
}

Задание:

public class SampleJob : IJob
{
    private readonly ISampleService _sampleService;

    public SampleJob(ISampleService sampleService)
    {
        _sampleService = sampleService;
    }

    public async Task Execute(IJobExecutionContext context)
    {
        await Task.FromResult(0);
    }
}
...