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.

ServiceCollectionExtensions is the entry point for adding ServiceComposer to an ASP.NET Core application. Call one of its AddViewModelComposition overloads inside ConfigureServices (or the WebApplicationBuilder.Services equivalent) to register the composition engine and all its internal services. Once the DI container is built, the companion extension methods on HttpRequest give composition handlers convenient access to the assembled ViewModel, the current composition context, and MVC model binding.

ServiceCollectionExtensions

Static class in the ServiceComposer.AspNetCore namespace.

AddViewModelComposition

Overload 1 — defaults only
public static void AddViewModelComposition(
    this IServiceCollection services,
    IConfiguration configuration = null)
Registers the ViewModel Composition pipeline with all default settings. The assembly scanner is enabled and will auto-discover composition handlers on startup.
services
IServiceCollection
required
The application service collection.
configuration
IConfiguration
The application configuration root. Pass this when you need to read IConfiguration inside a ViewModelCompositionOptions customization or custom handler. Accessing ViewModelCompositionOptions.Configuration without supplying this value throws an exception.
Overload 2 — with options callback
public static void AddViewModelComposition(
    this IServiceCollection services,
    Action<ViewModelCompositionOptions> config,
    IConfiguration configuration = null)
Registers the pipeline and immediately invokes config with a ViewModelCompositionOptions instance, allowing fine-grained control over assembly scanning, serialization, write support, and handler registration.
services
IServiceCollection
required
The application service collection.
config
Action<ViewModelCompositionOptions>
required
Delegate that receives a ViewModelCompositionOptions to configure the pipeline.
configuration
IConfiguration
The application configuration root. Required if ViewModelCompositionOptions.Configuration will be accessed at runtime.
Minimal setup
var builder = WebApplication.CreateBuilder();
builder.Services.AddRouting();
builder.Services.AddViewModelComposition();

var app = builder.Build();
app.MapCompositionHandlers();
app.Run();
Setup with options
builder.Services.AddViewModelComposition(options =>
{
    options.AssemblyScanner.Disable();
    options.RegisterCompositionHandler<MyProductHandler>();
    options.ResponseSerialization.DefaultResponseCasing = ResponseCasing.PascalCase;
}, builder.Configuration);

HttpRequestExtensions

Static class in the ServiceComposer.AspNetCore namespace. These extension methods are called from within composition handlers after the ViewModel has been assembled.

GetComposedResponseModel

public static dynamic GetComposedResponseModel(this HttpRequest request)
Returns the composed response ViewModel stored in HttpContext.Items as a dynamic object. Use this when the ViewModel type is not known statically.
request
HttpRequest
required
The current HTTP request.
Returns dynamic — the composed ViewModel, or null if none has been set yet.

GetComposedResponseModel<T>

public static T GetComposedResponseModel<T>(this HttpRequest request) where T : class
Returns the composed ViewModel cast to T. Throws InvalidCastException if the stored ViewModel cannot be cast, which typically means the registered IViewModelFactory does not produce instances of T.
request
HttpRequest
required
The current HTTP request.
Type parameter T — the expected ViewModel type; must be a reference type. Returns T — the strongly typed ViewModel.
public class ProductCompositionHandler : ICompositionRequestsHandler
{
    [HttpGet("/api/products/{id}")]
    public async Task Handle(HttpRequest request)
    {
        var vm = request.GetComposedResponseModel<ProductViewModel>();
        vm.ProductName = "Widget";
    }
}

GetCompositionContext

public static ICompositionContext GetCompositionContext(this HttpRequest request)
Returns the ICompositionContext for the current request, which exposes the request ID and event-raising capabilities.
request
HttpRequest
required
The current HTTP request.
Returns ICompositionContext.

SetActionResult

public static void SetActionResult(this HttpRequest request, ActionResult actionResult)
Stores a custom ActionResult that ServiceComposer will use as the HTTP response instead of the serialized ViewModel. Useful for returning redirect or error responses from a handler.
request
HttpRequest
required
The current HTTP request.
actionResult
ActionResult
required
The ActionResult to return. Only the first call per request takes effect.
request.SetActionResult(new NotFoundResult());

HttpRequestModelBinderExtension

Static class in the ServiceComposer.AspNetCore namespace. Provides MVC model binding inside composition handlers without requiring a controller.

Bind<T>

public static async Task<T> Bind<T>(this HttpRequest request) where T : new()
Binds the incoming request data (route values, query string, body, form) to a new instance of T using the MVC model binding pipeline. Returns the bound model directly.
request
HttpRequest
required
The current HTTP request.
Type parameter T — the model type. Must have a public parameterless constructor. Returns Task<T> — the bound model.
[HttpPost("/api/orders")]
public async Task Handle(HttpRequest request)
{
    var order = await request.Bind<OrderModel>();
    // use order.CustomerId, order.Items, etc.
}

TryBind<T>

public static Task<(T Model, bool IsModelSet, ModelStateDictionary ModelState)>
    TryBind<T>(this HttpRequest request) where T : new()
Attempts to bind the request to T and returns a tuple with the model, a flag indicating whether binding succeeded, and the ModelStateDictionary for validation error inspection.
request
HttpRequest
required
The current HTTP request.
Type parameter T — the model type. Must have a public parameterless constructor. Returns Task<(T Model, bool IsModelSet, ModelStateDictionary ModelState)>.
[HttpPost("/api/orders")]
public async Task Handle(HttpRequest request)
{
    var (model, isSet, modelState) = await request.TryBind<OrderModel>();
    if (!isSet || !modelState.IsValid)
    {
        request.SetActionResult(new BadRequestObjectResult(modelState));
        return;
    }
    // proceed with model
}
Note: Model binding requires MVC services to be registered. Call services.AddControllers() (or one of its variants) before AddViewModelComposition.

Build docs developers (and LLMs) love