This release concentrates on tweaking the DI story and fixing some found dependency issues.
# Quartz.Extensions.Hosting
A new package Quartz.Extensions.Hosting was created with the help of Andrew Lock. If you are using generic host and you don't need ASP.NET specific functionality like health checks, you can switch to this new package to reduce dependencies.
# Refining DI integration API
Some work was done to improve the MS DI integration API.
# Options pattern
Now the API uses options pattern
properly and you can attach your own configurators to alter QuartzOptions
.
// we can use options pattern to support hooking your own configuration
// because we don't use service registration api
// we need to manally ensure the job is present in DI
services.AddTransient<ExampleJob>();
services.Configure<SampleOptions>(Configuration.GetSection("Sample"));
services.AddOptions<QuartzOptions>()
.Configure<IOptions<SampleOptions>>((options, dep) =>
{
if (!string.IsNullOrWhiteSpace(dep.Value.CronSchedule))
{
var jobKey = new JobKey("options-custom-job", "custom");
options.AddJob<ExampleJob>(j => j.WithIdentity(jobKey));
options.AddTrigger(trigger => trigger
.WithIdentity("options-custom-trigger", "custom")
.ForJob(jobKey)
.WithCronSchedule(dep.Value.CronSchedule));
}
});
# ScheduleJob
A new shorthand was created to quickly define a job with trigger using a single call.
q.ScheduleJob<ExampleJob>(trigger => trigger
.WithIdentity("Combined Configuration Trigger")
.StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(7)))
.WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
.WithDescription("my awesome trigger configured for a job with single call")
);
# AddCalendar
You can now add calendars using the DI API.
const string calendarName = "myHolidayCalendar";
q.AddCalendar<HolidayCalendar>(
name: calendarName,
replace: true,
updateTriggers: true,
x => x.AddExcludedDate(new DateTime(2020, 5, 15))
);
q.AddTrigger(t => t
.WithIdentity("Daily Trigger")
.ForJob(jobKey)
.StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5)))
.WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
.WithDescription("my awesome daily time interval trigger")
.ModifiedByCalendar(calendarName)
);
# Microsoft SQL Server
Now Quartz no longer has hard dependency on Microsoft.Data.SqlClient
package.
Full framework defaults now back to same behavior as it was with Quartz 3.0 (using built-in System.Data.SqlClient driver).
# Full Framework
You can use either one of the two providers, SqlServer
(default) or SystemDataSqlClient
. Former uses System.Data.SqlClient
and latter
the new Microsoft.Data.SqlClient package.
If you choose to use the new package, make sure you have the NuGet package installed.
# .NET Core
You need to ensure you have Microsoft.Data.SqlClient package installed.
# Query plan cache pollution fix
There was an important fix for SQL Server where varying text parameter sizes caused query plan cache pollution. Now when no parameter size is defined for string parameter, default value of 4000 will be used. This problem has been present since the beginning.
# GitHub Issues
BREAKING CHANGES
- Remove dependency on Microsoft.Data.SqlClient (#912)
- LogContext moved from Quartz namespace to Quartz.Logging namespace (#915)
- For Full Framework, System.Data.SqlClient is again the default provider, Microsoft.Data can be used via provider MicrosoftDataSqlClient (#916)
NEW FEATURE
- Introduce separate Quartz.Extensions.Hosting (#911)
- You can now schedule job and trigger in MS DI integration with single .ScheduleJob call (#943)
- Support adding calendars to MS DI via AddCalendar<T> (#945)
FIXES
- Revert change in 3.1: CronExpression/cron trigger throwing
NotImplementedException
when calculating final fire time (#905) - Use 2.1 as the minimum version for the .NET Platform Extensions (#923)
- ServiceCollection.AddQuartz() should register default ITypeLoadHelper if none supplied (#924)
- SqlServer AdoJobStore SqlParameter without text size generates pressure on server (#939)
- DbProvider initialization logic should also read quartz.config (#951)
- LoggingJobHistoryPlugin and LoggingTriggerHistoryPlugin names are null with IoC configuration (#926)
- Improve options pattern to allow better custom configuration story (#955)