Skip to main content
Version: 1.1

3. Packages

Repo: Shumoul.Saas.BackgroundJobsFramework. All 5 published packages ship at version 1.0.0, targeting net9.0 only. A 6th, unpublished test project (Shumoul.BackgroundJobs.Tests, IsPackable=false) completes the repo.

3.1 Shumoul.BackgroundJobs.Contracts

Purpose: the generic runtime vocabulary — job identity, status, trigger type, priority, retry policy, tenant info, lock key, schedule request, execution result, failure category.

Responsibilities: enums and records/DTOs only. No logic beyond simple computed properties and static factory methods.

Depends on: nothing — zero ProjectReference/PackageReference beyond the SDK itself. A true leaf.

Forbidden dependencies: everything — this package must never gain a dependency on anything.

3.2 Shumoul.BackgroundJobs.Abstractions

Purpose: interfaces only — the runtime contracts (IBackgroundJob, executor, pipeline, execution context, scheduler, tenant context, distributed lock, failure classifier) plus the adapter contracts (Hangfire, tenant resolver, distributed lock, logging, notification).

Depends on: Contracts only.

Forbidden dependencies: any infrastructure package, any ERP assembly, Core, Adapters.

3.3 Shumoul.BackgroundJobs.Core

Purpose: the runtime engine itself — pipeline orchestration, execution wrapping, scheduling delegation, tenant scoping, distributed-lock delegation, failure classification. Owns the Core-level DI entry point AddBackgroundJobsFrameworkCore.

Depends on: Abstractions; Microsoft.Extensions.DependencyInjection.Abstractions 9.0.0; Microsoft.Extensions.Configuration.Abstractions 9.0.0 (present for future use — nothing in current Core source actually consumes configuration types yet).

Forbidden dependencies: Adapters (a sibling, never a chained dependency), Hangfire, EF Core, MultiTenancy, any ERP assembly — confirmed zero such references anywhere in Core.

3.4 Shumoul.BackgroundJobs.Adapters

Purpose: the framework's own infrastructure adapters — the only place in the framework where Hangfire and MultiTenancy types are referenced. This is the framework side of the two-tier adapter model — see §7 — Adapters.

Depends on: Abstractions; Hangfire.Core 1.8.21; Shumoul.Framework.MultiTenancy 1.0.77.

Forbidden dependencies: Core (a sibling, never a chained dependency), any ERP assembly, any Shumoul.Notification.* package.

3.5 Shumoul.BackgroundJobs (Entry Point)

Purpose: the module's single entry point — one-line DI wiring, AddShumoulBackgroundJobsFramework() => services.AddBackgroundJobsFrameworkCore(). Exposes no controllers — the Hangfire Dashboard's mounting, route, and authorization stay permanently host-owned (ADR-004).

Depends on: Core; Microsoft.Extensions.DependencyInjection.Abstractions 9.0.0.

Forbidden dependencies: Adapters — the host wires both packages independently, side by side, never through the entry package.

3.6 Shumoul.BackgroundJobs.Tests (unpublished)

Purpose: unit, DI/host-graph, adapter, and end-to-end tests for the framework itself.

Depends on: all 4 published packages via direct project reference (including Abstractions and Adapters directly, not merely the entry package); Microsoft.Extensions.DependencyInjection 9.0.9 (the full DI container, for BuildServiceProvider graph tests); xunit 2.9.2; Microsoft.NET.Test.Sdk 17.12.0.

Forbidden dependencies: any ERP assembly, any Notification Framework package.

3.7 Dependency graph

Confirmed against the actual .csproj files, not assumed from documentation: Core and Adapters are siblings — neither references the other, both depend only on Abstractions. The ERP host (Shumoul.Infrastructure.csproj) references exactly two packages directly:

<PackageReference Include="Shumoul.BackgroundJobs" Version="1.0.0" />
<PackageReference Include="Shumoul.BackgroundJobs.Adapters" Version="1.0.0" />

Core, Abstractions, and Contracts are pulled in transitively — the host never references them directly. There is zero ProjectReference from the ERP to any framework project, matching the platform's Dependency Law ("PackageReference only, across every module boundary").

3.8 Package graph — publication and distribution

PackagePublished to
Shumoul.BackgroundJobs.ContractsC:\MultiTenancy\ (developer staging) + local-packages\ (CI restore source) in the framework repo, then copied into the ERP repo's own local-packages\
Shumoul.BackgroundJobs.Abstractionssame
Shumoul.BackgroundJobs.Coresame
Shumoul.BackgroundJobs.Adapterssame
Shumoul.BackgroundJobs (entry)same

The ERP's nuget.config defines a LocalShumoul feed pointing at its own local-packages\ folder — this is the actual restore source any consumer build uses; C:\MultiTenancy\ is only the developer's local staging copy and is not consulted directly by CI or consumer builds. All 5 .nupkg files are confirmed present in the ERP's local-packages\ at version 1.0.0.

3.9 Ownership summary

OwnerOwnsMust NOT own
ContractsEnums, records, DTOs — pure data shapesAny logic, any dependency
AbstractionsEvery interface (runtime + adapter contracts)Any concrete implementation
CoreThe runtime engine's concrete implementationsHangfire, MultiTenancy, EF Core, any ERP type
AdaptersFramework-owned infrastructure adapters (Hangfire, MultiTenancy)Business logic, any ERP type, Core
Entry pointDI wiring onlyControllers, Hangfire Dashboard mounting
ERP HostJob-specific adapters, Hangfire-callable bridges, recurring-job registration/cutover, DI composition order, Dashboard authorization, job-tracking persistenceGeneric/reusable runtime logic that has no ERP dependency