Introduce anonymous/background-job-by-name support: add AnonymousJobArgs, IAnonymousJobHandlerRegistry and AnonymousJobHandlerRegistry, and an AnonymousJobExecutorAsyncBackgroundJob to execute JSON-based anonymous handlers. AbpBackgroundJobOptions now stores anonymous handlers and exposes registration/query helpers. Updated background job managers (Default, Hangfire, Quartz, RabbitMQ, TickerQ) to wrap registered anonymous jobs into AnonymousJobArgs when enqueuing and to depend on the handler registry and JSON serializer where needed. Removed the old dynamic handler types/APIs (DynamicBackgroundJobContext, IDynamicBackgroundJobHandlerProvider, DynamicBackgroundJobHandlerProvider) and related dynamic handling code; BackgroundJobConfiguration simplified (JobType non-nullable) and JobExecutionContext no longer carries JobName. Tests and demo code updated to use anonymous handlers and tracking. This change centralizes runtime-registered handlers keyed by job name and standardizes anonymous job payloads as JSON.
Introduce dynamic background job support so jobs can be registered and executed without a compile-time job type. Key changes:
- Add DynamicBackgroundJobContext, IDynamicBackgroundJobHandlerProvider and DynamicBackgroundJobHandlerProvider to allow registering/unregistering dynamic handlers at runtime.
- Extend BackgroundJobConfiguration with DynamicHandler and IsDynamic, and make JobType nullable for dynamic scenarios.
- Update AbpBackgroundJobOptions to use a ConcurrentDictionary for name lookup, and add methods to Add/Remove dynamic jobs and GetJobOrNull.
- Extend JobExecutionContext with JobName and propagate it through Hangfire/Quartz/RabbitMQ/TickerQ adapters and worker code.
- Update BackgroundJobExecuter to detect and execute dynamic handlers, deserialize/ensure dictionary args, and retain existing typed execution path.
- Add tests (DynamicJobExecutionTracker, runtime/compile-time dynamic handler tests) and register a sample dynamic job in test module.
- Update demo SampleJobCreator and DemoAppSharedModule to demonstrate compile-time and runtime dynamic job registration and enqueueing.
These changes enable flexible, dictionary-based job arguments and runtime registration of background job handlers while preserving existing typed job execution.
Avoids invalid casts when the provided args are not of runtime type TArgs. The method now checks for a direct TArgs instance and calls EnqueueAsync directly; otherwise it serializes and deserializes the args via Serializer to produce a TArgs instance before enqueuing. This preserves the fast path for matching types while safely handling boxed or different runtime argument representations.
Add non-generic EnqueueAsync(string jobName, object args, ...) to IBackgroundJobManager and implement it across providers. Implementations and helpers added/updated for Hangfire (IJsonSerializer usage, new HangfireJobExecutionAdapter), Quartz (new QuartzJobExecutionAdapter and job-data based enqueue), RabbitMQ (IJobQueue non-generic EnqueueAsync, JobQueueManager.GetAsync(jobName)), TickerQ (reflective CreateTickerRequest helper), and DefaultBackgroundJobManager (returns string ids). Also update NullBackgroundJobManager to throw for the new overload and extend tests to cover enqueueing by job name. These changes enable enqueueing jobs dynamically by name with serialized arguments and unify cross-provider execution paths.
When generating a project with a company name containing dots (e.g.,
'Demo.App.QoL'), the template replacement was incorrectly camelCasing
the company name as 'demo.App' instead of 'demo.app'.
This was because SolutionRenamer used ToCamelCase() on the entire string
rather than on each dot-separated segment individually. The runtime JS
proxy generator (JQueryProxyScriptGenerator.CamelCaseWithNamespace) applies
camelCase to each segment, causing a mismatch.
Added ToCamelCaseWithNamespace() helper to match runtime behavior.