Notification Event Handlers
Summary
There is no per-event handler class. A single EventNotificationResolver maps every consumed event to zero or more notification intents through one switch expression, and the dispatcher executes them.
Audience
Engineers, architects, QA, support and implementation partners.
Reference Content
The verified reference material for this topic is set out in the sections below.
Handler shape
The resolver is registered as a singleton and is stateless apart from its bound options. It exposes one method taking an envelope and returning a read-only list of intents.
A notification intent carries four things: the template key, the resolved recipient, the channel list and the template variables. It carries no delivery instruction — how an intent becomes a message is entirely the dispatcher's concern.
Dispatch mapping
One switch expression covers all 42 supported types. Handlers are grouped by shape rather than one-per-event:
| Handler group | Events | Form |
|---|---|---|
| Individually written | 10 | One private method each |
| Asset lifecycle | 6 | One method parameterised by event type and template key |
| Performance | 7 | One method parameterised by template key and audience |
| Training | 9 | One method parameterised by event type and template key |
| Helpdesk | 10 | One method parameterised by audience |
Any event type not matched by the switch returns an empty intent array, which the dispatcher records as a no-recipient outcome. Unknown events are absorbed, never thrown.
Variable extraction
Each handler deserializes the payload into its contract or local record, guards on a key identifier, and builds a string-to-string variable dictionary for template rendering. Missing values are coalesced to empty strings, and dates are formatted through a shared helper, so a sparse payload renders with blanks rather than failing.
A handler returns null when the payload cannot be parsed or its key identifier is empty; null becomes an empty intent list.
Channel selection
Each handler names a default channel set — in-app and email for all but one event, in-app only for the payroll-frozen event. Every default passes through a resolution helper that first consults an optional per-event configuration map.
When configuration supplies a non-empty channel array for the event type, that array replaces the default and each entry is normalised to canonical channel casing. The lookup is case-insensitive on the event type. This is the documented mechanism for adding or removing a channel for a pilot without a code change.
Multi-recipient handling
Only the Helpdesk group can produce more than one intent from one event. Its audience selector resolves requester, assignee, an admin fallback, or a combination, filters out nulls, and de-duplicates by recipient type and external reference before producing one intent per remaining recipient.
Execution
The dispatcher iterates intents, and for each iterates its distinct normalised channels, applying preference evaluation, address resolution and template resolution per channel before creating a message and delivering it. A channel with no resolvable address or a missing template is skipped and audited rather than failing the event.
Verified absence
There is no handler interface, no handler registry, no per-event handler class, no pipeline behavior, no middleware and no mediator. Adding an event means adding a switch case and a seeded template — which is exactly what the source comment states.
Classification
Implemented.
Requires confirmation
Whether the single-resolver shape is intended to scale past its current size requires confirmation.
Related Articles
See Also
Keywords
- Notification database
- Handlers
- Draft database documentation
Source References
microservices/src/notification-service/Application/EventNotificationResolver.csmicroservices/src/notification-service/Application/NotificationDispatcher.csmicroservices/src/notification-service/Application/NotificationOptions.csmicroservices/src/notification-service/Messaging/NotificationEventEnvelope.cs
Revision Information
- Status: Draft
- Last reviewed: 2026-07-21
- Review cycle: Quarterly