Skip to content

Commit 0f1df3a

Browse files
committed
Teach AddNCronJob() to accept a JobOptionBuilder
1 parent 4591198 commit 0f1df3a

3 files changed

Lines changed: 54 additions & 6 deletions

File tree

sample/MinimalSample/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
var builder = Host.CreateApplicationBuilder(args);
44

55
builder.Services.AddNCronJob((ILogger<Program> logger, TimeProvider timeProvider) =>
6-
logger.LogInformation("Hello World - The current date and time is {Time}", timeProvider.GetLocalNow())
7-
, "*/5 * * * * *");
6+
logger.LogInformation("Hello World - The current date and time is {Time}", timeProvider.GetLocalNow()),
7+
p => p.WithCronExpression("*/5 * * * * *"));
88

99
await builder.Build().RunAsync();

src/NCronJob/NCronJobExtensions.cs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,58 @@ public static IServiceCollection AddNCronJob(
120120
/// </code>
121121
/// </example>
122122
/// <returns>The modified service collection.</returns>
123+
[Obsolete("This method will be dropped in the next major version. Register untyped jobs using AddNCronJob(Delegate, Action<JobOptionBuilder>) overload instead.")]
123124
public static IServiceCollection AddNCronJob(this IServiceCollection services, Delegate jobDelegate, string cronExpression, TimeZoneInfo? timeZoneInfo = null)
124-
#pragma warning disable CS0618 // Type or member is obsolete
125-
=> services.AddNCronJob(builder => builder.AddJob(jobDelegate, cronExpression, timeZoneInfo));
126-
#pragma warning restore CS0618 // Type or member is obsolete
125+
=> services.AddNCronJob(jobDelegate, p => p.WithCronExpression(cronExpression, timeZoneInfo));
126+
127+
/// <summary>
128+
/// Adds a job using an anonymous delegate to the service collection that gets executed based on the given cron expression.
129+
/// This method allows for the scheduling of either synchronous or asynchronous tasks which are defined using lambda expressions.
130+
/// The delegate can depend on services registered in the dependency injection container, which are resolved at runtime.
131+
/// </summary>
132+
/// <param name="services">The service collection used to register the services.</param>
133+
/// <param name="jobDelegate">The delegate that represents the job to be executed. This delegate must return either void or Task.</param>
134+
/// <param name="options">The options that define how the job should be executed.</param>
135+
/// <example>
136+
/// Synchronous job example:
137+
/// <code>
138+
/// builder.Services.AddNCronJob((ILogger&lt;Program&gt; logger, TimeProvider timeProvider) =&gt;
139+
/// {
140+
/// logger.LogInformation("Hello World - The current date and time is {Time}", timeProvider.GetLocalNow());
141+
/// }, p => p.WithCronExpression("*/40 * * * * *"));
142+
/// </code>
143+
/// Asynchronous job example:
144+
/// <code>
145+
/// builder.Services.AddNCronJob(async (ILogger&lt;Program&gt; logger, TimeProvider timeProvider, CancellationToken ct) =&gt;
146+
/// {
147+
/// logger.LogInformation("Hello World - The current date and time is {Time}", timeProvider.GetLocalNow());
148+
/// await Task.Delay(1000, ct);
149+
/// }, p => p.WithCronExpression("*/40 * * * * *"));
150+
/// </code>
151+
/// Synchronous job with retry policy example:
152+
/// <code>
153+
/// builder.Services.AddNCronJob([RetryPolicy(retryCount: 4)] (JobExecutionContext context, ILogger&lt;Program&gt; logger) =&gt;
154+
/// {
155+
/// var attemptCount = context.Attempts;
156+
/// if (attemptCount &lt;= 4)
157+
/// {
158+
/// logger.LogWarning("TestRetryJob simulating failure.");
159+
/// throw new InvalidOperationException("Simulated operation failure in TestRetryJob.");
160+
/// }
161+
/// logger.LogInformation($"Job ran after {attemptCount} attempts");
162+
/// }, p => p.WithCronExpression("*/5 * * * * *"));
163+
/// </code>
164+
/// Synchronous job example with TimeZone:
165+
/// <code>
166+
/// builder.Services.AddNCronJob((ILogger&lt;Program&gt; logger, TimeProvider timeProvider) =&gt;
167+
/// {
168+
/// logger.LogInformation("Hello World - The current date and time is {Time}", timeProvider.GetLocalNow());
169+
/// }, p => p.WithCronExpression("*/40 * * * * *", TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time")));
170+
/// </code>
171+
/// </example>
172+
/// <returns>The modified service collection.</returns>
173+
public static IServiceCollection AddNCronJob(this IServiceCollection services, Delegate jobDelegate, Action<JobOptionBuilder> options)
174+
=> services.AddNCronJob(builder => builder.AddJob(jobDelegate, options));
127175

128176
/// <summary>
129177
/// Configures the host to use NCronJob. This will also start any given startup jobs and their dependencies.

tests/NCronJob.Tests/IntegrationTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ public async Task MinimalJobApiCanBeUsedForTriggeringCronJobs()
528528
ServiceCollection.AddNCronJob((Storage storage) =>
529529
{
530530
storage.Add("Done");
531-
}, Cron.AtEveryMinute);
531+
}, p => p.WithCronExpression(Cron.AtEveryMinute));
532532

533533
await StartNCronJob(startMonitoringEvents: true);
534534

0 commit comments

Comments
 (0)