Skip to content

Type Resolution

Type resolution registry

Type resolution is how ChokaQ maps a persisted string key in SQL to a .NET job type at runtime.

The persisted key is the durable contract. The CLR type is an implementation detail that can be renamed, moved, or versioned.

Where It Lives

JobTypeRegistry maintains two mappings:

DirectionUse
key to typeWorker dispatch when reading persisted jobs.
type to keyEnqueue path when serializing a new job.

Profiles populate the registry at startup.

Use semantic versioned keys:

csharp
CreateJob<SendEmailJob, EmailHandler>("email.send.v1");
CreateJob<CapturePaymentJob, CapturePaymentHandler>("billing.capture-payment.v1");

Avoid persisting short CLR names such as SendEmailJob. They are convenient until a namespace, assembly, or class name changes.

Strict Mode

ChokaQ:TypeResolution:RequireRegisteredJobTypes controls whether unregistered job types are allowed.

Strict registration is safer for production:

  • startup profiles define the contract surface;
  • unknown SQL rows fail clearly;
  • refactors do not silently change persistence keys.

Compatibility fallback can use assembly-qualified names, but that couples stored jobs to CLR identity.

Failure Modes

FailureCauseFix
Unknown type keyProfile missing or wrong key.Register the key or migrate the row.
Duplicate keyTwo profiles claim same key.Make keys globally unique.
Old row after refactorCLR fallback key changed.Use semantic keys and migration strategy.
Payload mismatchType resolved but payload contract changed.Version type keys and payload DTOs.

Architecture Decision

Why this pattern?

Durable jobs outlive code deployments. A stable string contract is safer than persisting raw CLR identity as the primary dispatch mechanism.

Trade-offs

Semantic keys require discipline. Developers must version contracts and keep old handlers available during migration windows.

Alternatives considered

AlternativeBenefitCost
Persist CLR type nameEasy at first.Breaks on refactor and assembly changes.
Store only numeric type IDsCompact.Requires central registry and harder debugging.
Dynamic assembly scanningFlexible.Slow, unsafe, and unpredictable in trimmed/AOT hosts.

Additional Questions

Why not persist CLR type names?
Because SQL rows can outlive refactors. Persisted contracts should be stable across code movement.

How do you roll out v2 payloads?
Register a new type key, keep v1 handler support until old rows drain, then retire the old key through an explicit migration/retention plan.

What should happen to an unknown type key?
It should fail visibly and be operator-diagnosable, not dispatch to an unsafe fallback silently.

Apache 2.0 Licensed