Я пытаюсь внедрить сервисы в мой класс SendEmailJob.Для планирования я использую стандартное внедрение ядра ASP и библиотеку Quartz.Я пытаюсь построить решение на основе этого ответа .Но все же я сталкиваюсь с проблемами с инъекцией.
У меня есть такая настройка кода:
//Startup.cs, ConfigureServices
ServiceAutoConfig.Configure(allServices);
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddTransient<IJobFactory, JobFactory>((provider) => new JobFactory(services.BuildServiceProvider()));
services.AddTransient<SendEmailJob>();
//Startup.cs, Configure
app.UseQuartz((quartz) => quartz.AddJob<SendEmailJob>("SendEmailJob", "Email", mailSettings.EmailSchedulerInterval));
Реализация SendEmailJob:
public class SendEmailJob : IJob
{
private readonly IMessageService _messageService;
private static bool IsBusy = false;
public SendEmailJob(IMessageService messageService)
{
_messageService = messageService;
}
public async Task Execute(IJobExecutionContext context)
{
try
{
if (IsBusy)
return;
IsBusy = true;
//...
}
catch (Exception error)
{
}
finally
{
IsBusy = false;
}
}
}
Реализация JobFacctory:
public class JobFactory : IJobFactory
{
protected readonly IServiceProvider _container;
public JobFactory(IServiceProvider container)
{
_container = container;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
try
{
var res = _container.GetService(bundle.JobDetail.JobType) as IJob;
return res;
}
catch (Exception ex)
{
//ERROR- Cannot resolve 'Quartz.Jobs.SendEmailJob' from root provider because it
// requires scoped service 'BLL.Base.UnitOfWork.Interfaces.IUnitOfWork'.
throw;
}
}
public void ReturnJob(IJob job)
{
(job as IDisposable)?.Dispose();
}
}
Реализация Quartz.cs
public class Quartz
{
private IScheduler _scheduler;
public static IScheduler Scheduler { get { return Instance._scheduler; } }
private static Quartz _instance = null;
public static Quartz Instance
{
get
{
if (_instance == null)
{
_instance = new Quartz();
}
return _instance;
}
}
private Quartz()
{
Init();
}
private async void Init()
{
_scheduler = await new StdSchedulerFactory().GetScheduler();
}
public IScheduler UseJobFactory(IJobFactory jobFactory)
{
Scheduler.JobFactory = jobFactory;
return Scheduler;
}
public async void AddJob<T>(string name, string group, int interval)
where T : IJob
{
IJobDetail job = JobBuilder.Create<T>()
.WithIdentity(name, group)
.Build();
ITrigger jobTrigger = TriggerBuilder.Create()
.WithIdentity(name + "Trigger", group)
.StartNow()
.WithSimpleSchedule(t => t.WithIntervalInSeconds(interval).RepeatForever()) // Mit wiederholung alle interval sekunden
.Build();
await Scheduler.ScheduleJob(job, jobTrigger);
}
public static async void Start()
{
await Scheduler.Start();
}
}
И реализация UseQuartzExtension:
public static void UseQuartz(this IApplicationBuilder app, Action<Quartz> configuration)
{
var jobFactory = new JobFactory(app.ApplicationServices);
Quartz.Instance.UseJobFactory(jobFactory);
configuration.Invoke(Quartz.Instance);
Quartz.Start();
}
И при введении IMessageService
в SendMailJob
возникает ошибка.Потому что это требует UnitOfWork
или не работает в любой другой области обслуживания.
Не могли бы вы объяснить, как правильно вводить?