You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. using Microsoft.Extensions.DependencyInjection;
  2. using Quartz;
  3. using Quartz.Spi;
  4. using System;
  5. using System.Collections.Concurrent;
  6. namespace MVCTemplate.Quartz
  7. {
  8. public class JobFactory : IJobFactory
  9. {
  10. protected readonly IServiceProvider _serviceProvider;
  11. protected readonly ConcurrentDictionary<IJob, IServiceScope> _scopes = new ConcurrentDictionary<IJob, IServiceScope>();
  12. public JobFactory(IServiceProvider serviceProvider)
  13. {
  14. _serviceProvider = serviceProvider;
  15. }
  16. public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
  17. {
  18. var scope = _serviceProvider.CreateScope();
  19. IJob job;
  20. try
  21. {
  22. job = scope.ServiceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;
  23. }
  24. catch
  25. {
  26. // Failed to create the job -> ensure scope gets disposed
  27. scope.Dispose();
  28. throw;
  29. }
  30. // Add scope to dictionary so we can dispose it once the job finishes
  31. if (!_scopes.TryAdd(job, scope))
  32. {
  33. // Failed to track DI scope -> ensure scope gets disposed
  34. scope.Dispose();
  35. throw new Exception("Failed to track DI scope");
  36. }
  37. return job;
  38. }
  39. public void ReturnJob(IJob job)
  40. {
  41. if (_scopes.TryRemove(job, out var scope))
  42. {
  43. // The Dispose() method ends the scope lifetime.
  44. // Once Dispose is called, any scoped services that have been resolved from ServiceProvider will be disposed.
  45. scope.Dispose();
  46. }
  47. }
  48. }
  49. }