I set up a Job
in which I injected a service from servicecollection
. The problem is that this job (Execute method) could not be run although before injecting any services, it was working properly.
I think the problem stems from Dependency Injection Lifetime
because when I change all lifetimes to Singleton
the job is fired. For the reason that DbContext
should be Transient
I have to solve it in another way.
Statup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<EFDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Cnn")).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking), ServiceLifetime.Transient);
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddTransient<CheckTransactionConfirmJob>();
services.AddTransient<CheckPaymentConfirmationScheduler>();
services.AddTransient<IPaymentRepository, EfPlanRepository>();
}
PaymentService.cs:
private async Task RunPaymentCheckerJob(Payment payment, Guid userId,
CheckPaymentConfirmationScheduler scheduler)
{
IJobDetail job = JobBuilder.Create<CheckTransactionConfirmJob>()
.WithIdentity(Guid.NewGuid().ToString(), "CheckConfirmationJob")
.UsingJobData("paymentId", payment.Id)
.UsingJobData("userId", userId)
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(Guid.NewGuid().ToString(), "CheckConfirmationGroup")
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(20)
.WithRepeatCount(12))
.ForJob(job)
.Build();
await scheduler.GetScheduler().ScheduleJob(job, trigger);
}
CheckTransactionConfirmJob.cs
public class CheckTransactionConfirmJob : IJob
{
private readonly IPaymentRepository _paymentRepository;
private readonly IServiceProvider _provider;
public CheckTransactionConfirmJob(IPaymentRepository paymentRepository, IServiceProvider provider)
{
_paymentRepository = paymentRepository;
_provider = provider;
}
public async Task Execute(IJobExecutionContext context)
{
try
{
/// business code
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
Quartz comes with two built-in alternatives for job factory which can be configured via either calling UseMicrosoftDependencyInjectionJobFactory
or UseMicrosoftDependencyInjectionScopedJobFactory
(deprecated).
For using Microsoft dependency UseMicrosoftDependencyInjectionJobFactory
should be called in ConfigureServices
method:
services.AddQuartz(q =>
{
q.UseMicrosoftDependencyInjectionJobFactory();
});