Search code examples
c#type-parameter

How can I parameterise this method and make it more flexible?


I'm writing a method to create Quartz scheduling jobs in C#. Currently it looks like this.

private async Task BuildJobs(int startHour, int endHour, int intervalOffsetSeconds = 0)
{
    try
    {
        var job = JobBuilder.Create<RepostTransactionsJob>()
            .WithIdentity(nameof(RepostTransactionsJob), TriggerGroup)
            .WithDescription("Reposting transactions")
            .Build();

        var trigger = TriggerBuilder.Create()
            .WithIdentity(string.Concat(nameof(RepostTransactionsJob), "-trigger"), TriggerGroup)
            .WithSchedule(CronScheduleBuilder.CronSchedule(string.Format("{2:ss} {2:mm} {0}-{1} ? * * *", startHour, endHour, TimeSpan.FromSeconds(intervalOffsetSeconds))))
            .Build();

        await this.scheduler.ScheduleJob(job, trigger);
    }
    catch (Exception ex)
    {
        this.logger.LogToLocal(ex.Message);
    }
}

However, I want to parameterise the RepostTransactionsJob part and I'm struggling. I've tried the following but that returns a build error.

Attempt:

private async Task BuildJobs<T>(int startHour, int endHour, int intervalOffsetSeconds = 0) where T : class
{
    try
    {
        var jobName = typeof(T).Name;

        var job = JobBuilder.Create<T>()
            .WithIdentity(jobName, TriggerGroup)
            .WithDescription("Reposting transactions")
            .Build();

        var trigger = TriggerBuilder.Create()
            .WithIdentity(string.Concat(jobName, "-trigger"), TriggerGroup)
            .WithSchedule(CronScheduleBuilder.CronSchedule(string.Format("{2:ss} {2:mm} {0}-{1} ? * * *", startHour, endHour, TimeSpan.FromSeconds(intervalOffsetSeconds))))
            .Build();

        await this.scheduler.ScheduleJob(job, trigger);
    }
    catch (Exception ex)
    {
        this.logger.LogToLocal(ex.Message);
    }
}

Build error:

The type 'T' cannot be used as a type parameter 'T' in the generic type or method 'JobBuilder.Create<T>()' There is no implicit reference conversion from 'T' to 'Quartz.IJob'

Solution

  • As the error indicates, the JobBuilder.Create has a IJob constraint:

    public static JobBuilder Create<T>()
    where T : IJob
    

    Therefore you need the same constraint on your method.

    private async Task BuildJobs<T>(int startHour, int endHour, int intervalOffsetSeconds = 0) where T : IJob