Schema-agnostic batch engine: default lifecycle, EF Core claim-and-process worker.
$ dotnet add package Fcop.BatchEngineUnified EF Core batch orchestration engine for idempotent row claiming, lifecycle management, and automatic retries.
Use in your Worker Service (Program.cs):
var builder = Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((ctx, cfg) =>
{
cfg.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
cfg.AddEnvironmentVariables();
})
.ConfigureServices((ctx, services) =>
{
// Register DbContext
services.AddDbContext<AppDbContext>(opts =>
{
opts.UseOracle(ctx.Configuration.GetConnectionString("Oracle"));
});
// Register engine (lifecycle + worker + orchestrator)
services.AddBatchEngine<AppDbContext, Batch, PurchaseOrder>();
// Register per-table adapters
services.AddScoped<IChildClaimSpec<PurchaseOrder>, PurchaseClaimSpec>();
services.AddScoped<IChildInBatchClaimSpec<PurchaseOrder>, PurchaseInBatchRetrySpec>();
services.AddScoped<IChildProcessor<PurchaseOrder>, PurchaseProcessor>();
// Bind options from appsettings.json (with optional overrides)
services.AddBatchEngineOptions(
ctx.Configuration,
batchRunOverride: opts =>
{
// Optional overrides
// opts.MaxRows = 50;
// opts.DelayMinutes = 5;
// opts.RetryBackoff = TimeSpan.FromMinutes(1);
// opts.MaxBatchAttempts = 3;
},
orchestratorOverride: orch =>
{
// Optional overrides
// orch.MaxParallelRuns = 4;
// orch.SpawnInterval = TimeSpan.FromSeconds(5);
// orch.AlwaysProbeWhenIdle = true;
});
// Hosted service runs orchestrator forever
services.AddHostedService(sp =>
{
var logger = sp.GetRequiredService<ILogger<PurchaseHostedService>>();
var scopeFactory = sp.GetRequiredService<IServiceScopeFactory>();
var batchRun = sp.GetRequiredService<BatchRunOptions>();
var orchRun = sp.GetRequiredService<BatchRunOrchestratorOptions>();
return new PurchaseHostedService(logger, scopeFactory, batchRun, orchRun);
});
})
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
});
await builder.Build().RunAsync();
{
"ConnectionStrings": {
"Oracle": "User Id=FCOP;Password=***;Data Source=***"
},
"BatchRunOptions": {
"MaxBatchAttempts": 3,
"RetryBackoff": "00:01:00",
"MaxRows": 100,
"DelayMinutes": 10
},
"BatchRunOrchestratorOptions": {
"MaxParallelRuns": 2,
"SpawnInterval": "00:00:10",
"AlwaysProbeWhenIdle": true
}
}
New → InProgress → Success | Failed | PartiallyFailed.UpdatedOn + RetryBackoff up to MaxBatchAttempts.RunUntilIdleAsync instances with MaxParallelRuns and SpawnInterval.Microsoft.EntityFrameworkCore, Microsoft.EntityFrameworkCore.Relational)Oracle.EntityFrameworkCore)