Custom Seeding
Use custom seeding logic to programmatically create initial jobs with full control over job properties, request data, and business logic.
UseTickerSeeder
Configure custom seeding functions for TimeTicker and CronTicker jobs on the core TickerOptionsBuilder. The same seeding pipeline runs regardless of whether you use the in-memory provider or EF Core.
Methods:
csharp
TickerOptionsBuilder<TTimeTicker, TCronTicker> UseTickerSeeder(
Func<ITimeTickerManager<TTimeTicker>, Task> timeSeeder);
TickerOptionsBuilder<TTimeTicker, TCronTicker> UseTickerSeeder(
Func<ICronTickerManager<TCronTicker>, Task> cronSeeder);
TickerOptionsBuilder<TTimeTicker, TCronTicker> UseTickerSeeder(
Func<ITimeTickerManager<TTimeTicker>, Task> timeSeeder,
Func<ICronTickerManager<TCronTicker>, Task> cronSeeder);Basic Example
csharp
Use `UseTickerSeeder` directly on `AddTickerQ` so seeding logic applies regardless of persistence provider (in-memory or EF Core):
```csharp
builder.Services.AddTickerQ(options =>
{
// Optional: disable auto seeding of code-defined cron tickers
options.IgnoreSeedDefinedCronTickers();
options.UseTickerSeeder(
async timeManager =>
{
await timeManager.AddAsync(new TimeTickerEntity
{
Function = "WarmUpCache",
ExecutionTime = DateTime.UtcNow.AddMinutes(1)
});
},
async cronManager =>
{
await cronManager.AddAsync(new CronTickerEntity
{
Function = "HealthCheck",
Expression = "0 */5 * * * *" // Every 5 minutes
});
});
});
## Accessing Services in Seeder
Since seeders run during application startup, you can't directly inject services. However, you can access configuration:
```csharp
var configuration = builder.Configuration;
builder.Services.AddTickerQ(options =>
{
options.UseTickerSeeder(
async timeManager =>
{
var adminEmail = configuration["Admin:Email"];
var jobDelayMinutes = int.Parse(configuration["Jobs:InitialDelayMinutes"] ?? "60");
await timeManager.AddAsync(new TimeTickerEntity
{
Function = "NotifyAdmin",
ExecutionTime = DateTime.UtcNow.AddMinutes(jobDelayMinutes),
Request = TickerHelper.CreateTickerRequest(new { Email = adminEmail })
});
},
null
);
});Error Handling
Handle errors in seeding functions:
csharp
builder.Services.AddTickerQ(options =>
{
options.UseTickerSeeder(
async timeManager =>
{
try
{
var result = await timeManager.AddAsync(new TimeTickerEntity
{
Function = "MyJob",
ExecutionTime = DateTime.UtcNow.AddHours(1)
});
if (!result.IsSucceeded)
{
// Log error but don't throw - seeding continues
Console.WriteLine($"Seeding failed: {result.Exception?.Message}");
}
}
catch (Exception ex)
{
// Log but don't throw - application startup shouldn't fail
Console.WriteLine($"Seeding exception: {ex.Message}");
}
},
null
);
});Seeding Custom Entity Types
When using custom entity types:
csharp
public class CustomTimeTicker : TimeTickerEntity<CustomTimeTicker>
{
public string TenantId { get; set; }
}
builder.Services.AddTickerQ<CustomTimeTicker, CustomCronTicker>(options =>
{
options.UseTickerSeeder(
async timeManager =>
{
await timeManager.AddAsync(new CustomTimeTicker
{
Function = "TenantSpecificJob",
TenantId = "tenant-001",
ExecutionTime = DateTime.UtcNow.AddDays(1)
});
},
null
);
});Best Practices
- Use batch operations when seeding multiple jobs
- Make seeding idempotent - handle cases where jobs might already exist
- Use configuration for environment-specific seeding
- Handle errors gracefully - don't let seeding failures block application startup
- Log seeding operations - track what was seeded for debugging
- Combine with automatic seeding - use both automatic and custom seeding
When to Use Custom Seeding
Use custom seeding when:
- You need to seed jobs with request data
- Jobs depend on configuration or environment
- You need conditional logic for seeding
- You want to seed one-time (TimeTicker) jobs
- Jobs require custom properties or relationships
- You need to seed jobs based on database state
Execution Order
Custom seeding executes after automatic cron seeding:
- Automatic cron seeding (from attributes)
- Custom TimeTicker seeding
- Custom CronTicker seeding
Logging
Custom seeding operations are logged:
[INF] TickerQ start seeding data: CustomTimeTicker
[INF] TickerQ completed seeding data: CustomTimeTickerWith OpenTelemetry, you'll see separate activities for each seeding operation.
See Also
- Automatic Seeding - Attribute-based cron job seeding
- Disable Seeding - Prevent automatic seeding
