EasyCore.Quartz.Oracle 8.3.0

dotnet add package EasyCore.Quartz.Oracle --version 8.3.0
                    
NuGet\Install-Package EasyCore.Quartz.Oracle -Version 8.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EasyCore.Quartz.Oracle" Version="8.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EasyCore.Quartz.Oracle" Version="8.3.0" />
                    
Directory.Packages.props
<PackageReference Include="EasyCore.Quartz.Oracle" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EasyCore.Quartz.Oracle --version 8.3.0
                    
#r "nuget: EasyCore.Quartz.Oracle, 8.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EasyCore.Quartz.Oracle@8.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EasyCore.Quartz.Oracle&version=8.3.0
                    
Install as a Cake Addin
#tool nuget:?package=EasyCore.Quartz.Oracle&version=8.3.0
                    
Install as a Cake Tool

โฑ๏ธ EasyCore.Quartz

EasyCore.Quartz is a production-oriented job scheduling library for .NET 8. Built on Quartz.NET, it provides attribute-based jobs, an English ops dashboard, REST management APIs, dynamic HTTP jobs, and persistence with clustering for MySQL / SQL Server / PostgreSQL / Oracle.

.NET C# Quartz Dashboard DB License Version


๐ŸŒ Language


๐Ÿ“š Table of Contents

Part I โ€” Overview & Architecture

Part II โ€” Getting Started

Part III โ€” Dashboard ยท REST ยท HTTP Jobs

Part IV โ€” Persistence & Production


1. Positioning

EasyCore.Quartz makes Quartz easy, operable, and production-safe in ASP.NET Core:

Pain point EasyCore.Quartz approach
Manual job wiring IEasyCoreJob + [EasyCoreCron] auto-discovery
No ops UI Optional package EasyCore.Quartz.Dashboard (/easy-quartz)
Split management APIs Shared IJobManagementService (Dashboard + REST)
Multi-DB persistence Separate MySQL / SQL Server / PostgreSQL / Oracle packages
Swallowed exceptions JobWrapper logs and rethrows
Accidental public exposure Dashboard Basic Auth; username/password required

1.1 Design Principles

Principle Meaning
Low friction One extension method + one attribute to get running
Operable Full dashboard: Overview / Jobs / History / โ€ฆ
Pluggable storage Core and DB packages are separate
Failure-aware Exceptions propagate; History records outcomes
Secure by default Empty authorization list โ‡’ reject dashboard access

1.2 Repository Layout

EasyCore.Quartz/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ EasyCore.Quartz/                 # Core: discovery, management, REST, History
โ”‚   โ”œโ”€โ”€ EasyCore.Quartz.Dashboard/       # English ops dashboard
โ”‚   โ”œโ”€โ”€ EasyCore.Quartz.MySql/
โ”‚   โ”œโ”€โ”€ EasyCore.Quartz.SqlServer/
โ”‚   โ”œโ”€โ”€ EasyCore.Quartz.PostgreSql/
โ”‚   โ””โ”€โ”€ EasyCore.Quartz.Oracle/
โ”œโ”€โ”€ demo/
โ”‚   โ”œโ”€โ”€ WebApp.Quartz.InMemory/          # :5101 โ€” each demo owns SampleJob
โ”‚   โ”œโ”€โ”€ WebApp.Quartz.MySql/             # :5102
โ”‚   โ”œโ”€โ”€ WebApp.Quartz.SqlServer/         # :5103
โ”‚   โ”œโ”€โ”€ WebApp.Quartz.PostgreSql/        # :5104
โ”‚   โ””โ”€โ”€ WebApp.Quartz.Oracle/            # :5105
โ”œโ”€โ”€ tests/EasyCore.Quartz.Tests/
โ””โ”€โ”€ docs/svg/

2. Architecture

2.1 Component Diagram

architecture-en

2.2 Job Lifecycle

sequence-en

2.3 Data Flow

[EasyCoreCron Job]
       โ”‚
       โ–ผ
 JobTypeDiscovery โ”€โ”€โ–บ JobWrapper<T> โ”€โ”€โ–บ Quartz Scheduler
       โ”‚                                      โ”‚
       โ”‚                                      โ–ผ
       โ”‚                            JobExecutionHistoryListener
       โ”‚                                      โ”‚
       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ IJobManagementService โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                      โ”‚
           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
           โ–ผ                     โ–ผ
     Dashboard UI           REST api/quartz

3. NuGet Packages

Package Role Required
EasyCore.Quartz Core, REST, History โœ…
EasyCore.Quartz.Dashboard English ops dashboard + Basic Auth Optional
EasyCore.Quartz.MySql MySQL store + schema bootstrap Optional
EasyCore.Quartz.SqlServer SQL Server store + schema bootstrap Optional
EasyCore.Quartz.PostgreSql PostgreSQL store + schema bootstrap Optional
EasyCore.Quartz.Oracle Oracle store + schema bootstrap Optional

4. Database Comparison

Capability In-Memory MySQL SQL Server PostgreSQL Oracle
Package Core only .MySql .SqlServer .PostgreSql .Oracle
Persistence โŒ โœ… โœ… โœ… โœ…
Clustering โŒ โœ… โœ… โœ… โœ…
AutoCreateSchema โ€” โœ… โœ… โœ… โœ…
Table prefix โ€” QRTZ_ QRTZ_ QRTZ_ QRTZ_
Typical use Local trial Common Linux stack Enterprise Windows Cloud / open source Legacy enterprise

4.1 Decision Tree

Need persistence / multi-node?
โ”œโ”€โ”€ No  โ†’ In-Memory (WebApp.Quartz.InMemory)
โ””โ”€โ”€ Yes โ†’ Pick your existing database
        โ”œโ”€โ”€ MySQL / MariaDB โ†’ EasyCore.Quartz.MySql
        โ”œโ”€โ”€ SQL Server โ†’ EasyCore.Quartz.SqlServer
        โ”œโ”€โ”€ PostgreSQL โ†’ EasyCore.Quartz.PostgreSql
        โ””โ”€โ”€ Oracle โ†’ EasyCore.Quartz.Oracle

5. Requirements

Item Requirement
.NET 8.0+
Host ASP.NET Core (Web / API)
Quartz.NET 3.14 (brought by core package)
Database Optional; required only for persistence

6. Installation

dotnet add package EasyCore.Quartz
dotnet add package EasyCore.Quartz.Dashboard

# pick one as needed
dotnet add package EasyCore.Quartz.MySql
dotnet add package EasyCore.Quartz.SqlServer
dotnet add package EasyCore.Quartz.PostgreSql
dotnet add package EasyCore.Quartz.Oracle

7. Quick Start (3 minutes)

7๏ธโƒฃ.1๏ธโƒฃ Define a job

using EasyCore.Quartz;
using Quartz;

[EasyCoreCron("0/10 * * * * ?")]
[EasyCoreDisallowConcurrentExecution]
public sealed class SampleJob : IEasyCoreJob
{
    private readonly ILogger<SampleJob> _logger;
    public SampleJob(ILogger<SampleJob> logger) => _logger = logger;

    public Task Execute(IJobExecutionContext context)
    {
        _logger.LogInformation("SampleJob running at {Time}", DateTimeOffset.Now);
        return Task.CompletedTask;
    }
}

Disable without deleting code:

[EasyCoreDisableJob]
[EasyCoreCron("0 0 * * * ?")]
public sealed class DisabledJob : IEasyCoreJob
{
    public Task Execute(IJobExecutionContext context) => Task.CompletedTask;
}

7๏ธโƒฃ.2๏ธโƒฃ Register services (including dashboard)

// Reference EasyCore.Quartz.Dashboard
builder.Services.AddEasyCoreQuartz(options =>
{
    options.AddAssemblyFrom<SampleJob>();
    options.TimeZoneOffsetHours = +8;
    options.AutoCreateSchema = true;

    // RAM by default. For persistence, uncomment one:
    // options.UseMySql(m => m.ConnectionString = "...");
    // options.UseSqlServer(s => s.ConnectionString = "...");
    // options.UsePostgreSql(p => p.ConnectionString = "...");
    // options.UseOracle(o => o.ConnectionString = "...");

    // Dashboard URL = app base URL + PathMatch
    // No app.UseEasyCoreQuartzDashboard(...) needed
    options.UseEasyCoreQuartzDashboard(dash =>
    {
        dash.PathMatch = "/easy-quartz";
        dash.Username = "admin";
        dash.Password = "admin123";
    });
});

Open: http://localhost:<port>/easy-quartz/ (browser prompts for username/password)


8. Attributes & Options

Attribute / Option Description
IEasyCoreJob Marker interface (extends Quartz IJob)
[EasyCoreCron] Cron, JobKey, JobGroup, Misfire, RequestRecovery
[EasyCoreDisableJob] Skip auto-registration
[EasyCoreDisallowConcurrentExecution] Prevent overlapping runs
AddAssembly / AddAssemblyFrom<T> Explicit discovery
AutoCreateSchema Idempotent DDL on startup (disable in prod)
HistoryCapacity In-memory history ring buffer size (default 200); Overview success/failure counts are window stats
HttpJobTimeout HTTP job timeout (default 30s)
HttpJobBlockPrivateNetworks Default true โ€” blocks loopback/private/metadata hosts
HttpJobAllowedHosts HTTP job host allow-list (e.g. localhost)
TablePrefix Default QRTZ_ (must match DDL)
MaxConcurrency Thread pool size; 0 = auto

9. Dashboard (English UI)

9.1 Preview

dashboard-preview

9.2 Pages

Page Icon Capabilities
Overview ๐Ÿ“Š Scheduler status, job/trigger counts, failure stats
Jobs ๐Ÿ“‹ List; Pause / Resume / Trigger / Delete / Edit Cron / Detail
Recurring ๐Ÿ” Cron jobs only
Executing โšก Currently running jobs
HTTP Jobs ๐ŸŒ Create / update HTTP invoke jobs
History ๐Ÿ“œ Recent executions (node-local memory)
Servers ๐Ÿ–ฅ๏ธ Scheduler name / InstanceId / Store

โš ๏ธ History is a process-local ring buffer. Overview success/failure counts reflect the current window only (not lifetime totals) and are not shared across nodes.

9.3 Authorization (HTTP Basic Auth)

options.UseEasyCoreQuartzDashboard(dash =>
{
    dash.PathMatch = "/easy-quartz"; // full URL = app base + this path
    dash.Username = "admin";         // required
    dash.Password = "admin123";      // required
});
Option Description
PathMatch Relative path (default /easy-quartz)
Username / Password Basic Auth credentials (required; middleware auto-mounted)
BasicAuthAuthorizationFilter Enabled by default
LocalRequestsOnlyAuthorizationFilter Optional; append to dash.Authorization
Custom IEasyCoreQuartzAuthorizationFilter Replace or stack for production

10. REST API

Base path: api/quartz

Method Path Description
GET /overview Overview
GET /jobs All jobs
GET /jobs/{group}/{name} Job detail
GET /recurring Cron jobs
GET /executing Executing jobs
GET /history?take=100 History
PUT /jobs/{group}/{name}/pause Pause
PUT /jobs/{group}/{name}/resume Resume
PUT /jobs/{group}/{name}/cron?cron=... Update cron
DELETE /jobs/{group}/{name} Delete
POST /jobs/{group}/{name}/trigger Trigger now
POST /http-jobs Add/update HTTP job

11. HTTP Jobs

Create via Dashboard HTTP Jobs or REST:

{
  "jobName": "PingApi",
  "jobGroup": "DEFAULT",
  "url": "https://example.com/demo/ping",
  "method": "GET",
  "cron": "0/30 * * * * ?",
  "headers": { "X-Trace": "demo" },
  "body": "",
  "description": "Health ping"
}
Capability Notes
Method GET / POST / PUT / DELETE / PATCH (case-insensitive)
Body JSON validated for POST/PUT/PATCH
Timeout HttpJobTimeout (default 30s)
SSRF Blocks loopback/private/link-local/metadata by default; allow via HttpJobAllowedHosts
Failure Non-2xx โ‡’ exception โ‡’ History failure

To call a local demo API, allow the host explicitly:

options.HttpJobAllowedHosts.Add("localhost");
options.HttpJobAllowedHosts.Add("127.0.0.1");

12. Database Configuration

All providers use table prefix QRTZ_.

๐Ÿฌ MySQL

options.UseMySql(mysql =>
{
    mysql.ConnectionString =
        "server=localhost;port=3306;user id=root;password=***;database=EasyCoreQuartz;";
});

๐ŸŸฆ SQL Server

options.UseSqlServer(sql =>
{
    sql.ConnectionString =
        "Server=.;Database=EasyCoreQuartz;User Id=sa;Password=***;TrustServerCertificate=True;";
});

๐Ÿ˜ PostgreSQL

options.UsePostgreSql(pg =>
{
    pg.ConnectionString =
        "Host=localhost;Port=5432;Database=EasyCoreQuartz;Username=postgres;Password=***";
});

๐Ÿ”ถ Oracle

options.UseOracle(ora =>
{
    ora.ConnectionString =
        "User Id=quartz;Password=***;Data Source=localhost:1521/ORCL";
});

Production DDL tip

options.AutoCreateSchema = false; // disable auto DDL in production

Apply official Quartz scripts (or freeze scripts generated in staging) through your migration pipeline.


13. Clustering & Concurrency

Option Default Description
CheckinInterval 5s Cluster check-in interval
CheckinMisfireThreshold 10s Check-in misfire threshold
MaxConcurrency 20 Thread pool; 0 = auto

Configuring any persistent provider enables Quartz clustering.

Prevent overlapping execution:

[EasyCoreDisallowConcurrentExecution]
[EasyCoreCron("0/5 * * * * ?")]
public sealed class ExclusiveJob : IEasyCoreJob { /* ... */ }

14. Demo Projects

Project Store Port Command
WebApp.Quartz.InMemory RAM 5101 dotnet run --project demo/WebApp.Quartz.InMemory
WebApp.Quartz.MySql MySQL 5102 dotnet run --project demo/WebApp.Quartz.MySql
WebApp.Quartz.SqlServer SQL Server 5103 dotnet run --project demo/WebApp.Quartz.SqlServer
WebApp.Quartz.PostgreSql PostgreSQL 5104 dotnet run --project demo/WebApp.Quartz.PostgreSql
WebApp.Quartz.Oracle Oracle 5105 dotnet run --project demo/WebApp.Quartz.Oracle

Each demo has its own Jobs/SampleJob.cs โ€” open and edit locally, no cross-project reference.

dotnet run --project demo/WebApp.Quartz.InMemory
# open http://localhost:5101/easy-quartz

For DB demos, update ConnectionStrings:Quartz in the corresponding appsettings.json first.


15. Migrating from older versions

8.0.0 is a breaking release (relative to earlier Quarzt* naming):

Older 8.0
QuarztOptions EasyCoreQuartzOptions
api/Quarzt api/quartz
Typo Quarzt Corrected everywhere
Scan all BaseDirectory DLLs EntryAssembly + AddAssembly
Swallowed job exceptions Log and rethrow
Prefix qrtz_ Unified QRTZ_
Mixed licenses MIT

16. Production Checklist

  • Use a strong dashboard password (never ship demo credentials publicly)
  • Set AutoCreateSchema = false with reviewed migrations
  • Keep connection strings in a secret store
  • Monitor logs and History window failure counts (not lifetime totals)
  • HTTP jobs: review HttpJobAllowedHosts / egress policy; do not casually disable private-network blocking
  • Set MaxConcurrency explicitly under heavy load
  • Validate cron expressions before deploy
  • Multi-node setups must share the same store and table prefix

17. FAQ

Q: Dashboard returns 401?
A: The browser prompts for Basic Auth. Use the configured Username / Password. Enabling the dashboard without credentials throws at startup.

Q: Does RAM mode include the dashboard?
A: Yes. Reference EasyCore.Quartz.Dashboard and call options.UseEasyCoreQuartzDashboard(...).

Q: Why is History different across nodes?
A: History is a process-local ring buffer; Overview success/failure counts cover the current window only. Use your logging/audit stack for cross-node history.

Q: HTTP job to localhost is rejected?
A: SSRF protection is on by default. Add the host to options.HttpJobAllowedHosts, or disable HttpJobBlockPrivateNetworks only in controlled environments.

Q: Does default Method=GET fail validation?
A: No. Validation is case-insensitive in 8.0.

Q: How do I scan only my business assembly?
A: options.AddAssemblyFrom<YourJob>() or options.AddAssembly(asm).


18. License

MIT โ€” see LICENSE.


๐Ÿค Contributing

  1. Fork and create a feature branch
  2. Add tests under tests/EasyCore.Quartz.Tests
  3. Run dotnet test and dotnet build EasyCore.Quartz.sln
  4. Open a pull request

Issues and PRs are welcome ๐Ÿš€

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
8.3.0 130 7/21/2026
8.0.1 103 7/17/2026