Skip to main content

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.

ICompositionEventsSubscriber provides fine-grained, route-scoped event handling within the ServiceComposer pipeline. Unlike ICompositionEventsHandler<TEvent> — which is invoked globally regardless of route — an ICompositionEventsSubscriber is only activated on routes that match its HTTP method and route template attributes. This makes it the right choice whenever you need event reactions that are tightly scoped to a particular endpoint. Implementations are discovered by the assembly scanner, registered as transient services, and called during the composition lifecycle to register their lambda-based subscriptions before the composition handlers run.

Namespace

ServiceComposer.AspNetCore

Interface definition

public interface ICompositionEventsSubscriber
{
    void Subscribe(ICompositionEventsPublisher publisher);
}
ICompositionEventsPublisher is injected into Subscribe by the pipeline. It exposes one method:
public interface ICompositionEventsPublisher
{
    void Subscribe<TEvent>(CompositionEventHandler<TEvent> handler);
}
Use publisher.Subscribe<TEvent>(handler) to register a CompositionEventHandler<TEvent> delegate that will be invoked when any composition handler raises TEvent on the matched route.
public delegate Task CompositionEventHandler<in TEvent>(TEvent @event, HttpRequest httpRequest);

Methods

Subscribe

Called once per matched request, before composition handlers execute. Register one or more event handlers by calling publisher.Subscribe<TEvent>.
publisher
ICompositionEventsPublisher
required
The event publisher scoped to the current composition request and route. Call publisher.Subscribe<TEvent>(handler) for each event type this subscriber wants to handle on the matched route.
Returns void.

Route binding

Decorate the implementing class (or the Subscribe method) with standard ASP.NET Core routing attributes — [HttpGet], [HttpPost], [HttpPut], [HttpDelete] — to declare the route(s) this subscriber should be active on. The assembly scanner reads these attributes and maps the subscriber to the appropriate composition endpoints.
An ICompositionEventsSubscriber without a route attribute will not be associated with any endpoint and will never be called. Always annotate the class or method with at least one HTTP method attribute.

Usage example

The following example shows a subscriber that is active only on GET /route-based-handler/{some-id}. When AnEvent is raised by any handler on that route, the lambda receives it and writes to the ViewModel.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using ServiceComposer.AspNetCore;

public class RouteBasedEventHandler : ICompositionEventsSubscriber
{
    [HttpGet("/route-based-handler/{some-id}")]
    public void Subscribe(ICompositionEventsPublisher publisher)
    {
        publisher.Subscribe<AnEvent>((@event, request) =>
        {
            var vm = request.GetComposedResponseModel();
            vm.EventValue = @event.SomeValue;
            return Task.CompletedTask;
        });
    }
}
To publish the event that this subscriber handles, a request handler calls RaiseEvent on the same route:
public class EventPublishingHandler : ICompositionRequestsHandler
{
    [HttpGet("/route-based-handler/{some-id}")]
    public async Task Handle(HttpRequest request)
    {
        var context = request.GetCompositionContext();
        await context.RaiseEvent(new AnEvent(SomeValue: "This is the value"));
    }
}

Choosing between ICompositionEventsSubscriber and ICompositionEventsHandler

ConcernICompositionEventsSubscriberICompositionEventsHandler<TEvent>
Route scopeSpecific routes onlyAll routes
Registration styleLambda delegateClass-based
Multiple event typesMultiple Subscribe<T> calls in one methodOne class per event type
Typical use caseTightly coupled route logicCross-cutting concerns

DI registration

The assembly scanner discovers and registers ICompositionEventsSubscriber implementations automatically as transient services when AddViewModelComposition is called:
builder.Services.AddViewModelComposition();
Explicit registration is also supported:
builder.Services.AddViewModelComposition(options =>
{
    options.RegisterCompositionHandler<RouteBasedEventHandler>();
});

Build docs developers (and LLMs) love