【发布时间】:2018-09-19 08:12:35
【问题描述】:
我正在尝试将服务注入到我的 SendEmailJob 类中。 我使用标准的 ASP Core 依赖注入和 Quartz 库进行调度。 我正在尝试基于this answer 构建解决方案。但我仍然面临注射问题。
我有这样的代码设置:
//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 或在任何其他范围服务上失败。
你能解释一下如何正确注入吗?
【问题讨论】:
-
不需要注册IMessageService吗?
-
@MattjeS 已配置。观察 Startup.cs 的变化。忘记在这里指定它
标签: c# asp.net-core dependency-injection quartz.net