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.

ICompositionRequestsHandler is the primary building block of a ServiceComposer composition pipeline. Each implementation is responsible for handling a single HTTP request by appending its slice of data to the shared ViewModel. Multiple handlers can be registered against the same route and are invoked in parallel — each handler writes its own fragment of the response without being aware of the others. Implementations are discovered automatically by the assembly scanner and registered with the ASP.NET Core dependency-injection container as transient services. No manual service registration is required.

Namespace

ServiceComposer.AspNetCore

Interface definition

public interface ICompositionRequestsHandler
{
    Task Handle(HttpRequest request);
}

Methods

Handle

Invoked by the ServiceComposer pipeline when an incoming HTTP request matches the route declared on the implementing class.
request
HttpRequest
required
The current ASP.NET Core HttpRequest. Use request.GetComposedResponseModel() to obtain the shared dynamic ViewModel, and request.GetCompositionContext() to obtain the ICompositionContext needed to raise events.
Returns Task — a task that completes when the handler has finished contributing its data.

Route binding

To associate a handler with an HTTP route, decorate the class or the Handle method with standard ASP.NET Core routing attributes such as [HttpGet], [HttpPost], [HttpPut], or [HttpDelete]. ServiceComposer maps these attributes to endpoint routes during startup.
[HttpGet("/product/{id}")]
public Task Handle(HttpRequest request) { ... }
A handler class may carry one or more route attributes. Each route attribute creates a separate composition endpoint. Two different handler classes that declare the same route pattern will both be invoked in parallel when that route is matched.

Accessing the ViewModel

Inside Handle, call the GetComposedResponseModel() extension method to get the shared, dynamic ViewModel object that all handlers targeting the same route write into:
var vm = request.GetComposedResponseModel();
vm.SomeProperty = value;
A strongly typed overload is available when a custom IViewModelFactory creates a concrete type:
var vm = request.GetComposedResponseModel<MyViewModel>();
vm.SomeProperty = value;

Usage example

The following handler is part of a GET /product/{id} composition. It reads data from the Sales domain and appends pricing information to the shared ViewModel.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using ServiceComposer.AspNetCore;

public class SalesProductInfo : ICompositionRequestsHandler
{
    [HttpGet("/product/{id}")]
    public Task Handle(HttpRequest request)
    {
        var vm = request.GetComposedResponseModel();

        // Retrieve product details from the Sales database or service
        vm.ProductId = request.HttpContext.GetRouteValue("id").ToString();
        vm.ProductPrice = 100;

        return Task.CompletedTask;
    }
}
A second handler targeting the same route would run in parallel and contribute its own properties to vm without knowing about SalesProductInfo.

DI registration

ServiceComposer’s assembly scanner registers every class that implements ICompositionRequestsHandler as a transient service automatically. Call AddViewModelComposition in Program.cs to enable this:
builder.Services.AddViewModelComposition();
You can also register handlers explicitly via ViewModelCompositionOptions.RegisterCompositionHandler<T>() when you prefer to opt out of automatic scanning:
builder.Services.AddViewModelComposition(options =>
{
    options.RegisterCompositionHandler<SalesProductInfo>();
});
Handlers are registered as transient. If your handler needs singleton or scoped dependencies, inject them through constructor parameters — ASP.NET Core’s DI system resolves them on each request.

Build docs developers (and LLMs) love