Composition handlers run independently and are deliberately designed to be unaware of each other. However, some scenarios require coordination — the most common being the composition of lists. When building a page that shows a list of products, one handler might supply identifiers while another needs to enrich each item with additional data. Events provide a lightweight, in-process signalling mechanism that keeps handlers decoupled while still allowing them to react to each other’s output.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ServiceComposer/ServiceComposer.AspNetCore/llms.txt
Use this file to discover all available pages before exploring further.
Composing lists of composed elements (master-detail type outputs) is one of the primary motivations for the events API. Events are synchronous and in-memory — they are not serializable and do not cross process boundaries.
Defining an event
Events are plain .NET types — classes or records. There are no base classes or interfaces to implement:Publishing events
A handler publishes an event by first obtaining theICompositionContext from the request, then calling RaiseEvent:
RaiseEvent is awaitable. All subscribers registered for the event type are invoked synchronously (in-process) before RaiseEvent returns.
Subscribing to events
ServiceComposer provides two subscription APIs with different scopes.- Generic Event Handler
- Route-Based Subscriber
Implement This handler is invoked every time
ICompositionEventsHandler<TEvent> to subscribe to an event across all routes. The assembly scanner discovers these classes at startup and registers them in the DI container as transient components — so they fully support constructor injection.AnEvent is raised, regardless of which route is being handled.Interface contracts
The three interfaces involved in event-based coordination are:When to use which
ICompositionEventsHandler<TEvent>
Use when: the same event is handled identically across all routes. Discovery is automatic; the handler benefits from DI and can have scoped or transient dependencies injected via the constructor.
ICompositionEventsSubscriber
Use when: the same event requires different behaviour depending on the current route (e.g. GET vs POST), or when you only want to react to the event on a subset of routes. The
[Http*] attribute provides fine-grained control.