Skip to content

AddPerspectiveServices

Verified by tests

ServiceRegistrationGeneratorTests — library CI run #31657041675 (2026-08-13)

AddPerspectiveServices is a source-generated extension method that registers all discovered Perspective implementations with the dependency injection container.

Updated

AddWhizbang() invokes this method automatically via ServiceRegistrationCallbacks — an explicit call is only needed when registering services without AddWhizbang(), or with different options.

Signature

Signature

public static IServiceCollection AddPerspectiveServices(
    this IServiceCollection services,
    Action<ServiceRegistrationOptions>? configure = null)

Parameters

Parameter Type Description
services IServiceCollection The service collection to add registrations to
configure Action<ServiceRegistrationOptions>? Optional configuration action

Returns

IServiceCollection - The service collection for method chaining.

Basic Usage

Register Perspective Services

var builder = WebApplication.CreateBuilder(args);

// Register all discovered Perspective implementations
builder.Services.AddPerspectiveServices();

With Options

Register with Options

// Disable self-registration
builder.Services.AddPerspectiveServices(options =>
    options.IncludeSelfRegistration = false);

What Gets Registered

The source generator discovers classes that: - Implement IPerspectiveFor<TModel, TEvent...> or IPerspectiveWithActionsFor<TModel, TEvent...> — either directly (with closed generic arguments) or through a user-defined interface that extends one of them - Are not abstract

For each discovered Perspective, it generates:

Generated Registration

// Interface registration
services.AddTransient<IPerspectiveFor<OrderSummary, OrderCreated, OrderShipped>, OrderSummaryPerspective>();

// Self-registration (when IncludeSelfRegistration = true)
services.AddTransient<OrderSummaryPerspective>();

When the class implements a user-defined interface extending a Whizbang perspective interface, the registration targets the user interface instead.

Registration Lifetime

All Perspectives are registered as Transient services: - Fresh instance per resolution - No accidental state sharing — perspectives are pure functions - Any scoped dependencies come from the resolving scope

Example Perspective

Perspectives are pure functions — each Apply method takes the current read-model state and an event, and returns the new state. No I/O, no injected services:

Example Perspective Implementation

public class OrderSummaryPerspective :
  IPerspectiveFor<OrderSummary, OrderCreated, OrderShipped> {

  public OrderSummary Apply(OrderSummary currentData, OrderCreated @event) =>
    new OrderSummary {
      OrderId = @event.OrderId,
      CustomerId = @event.CustomerId,
      Status = OrderStatus.Created,
      CreatedAt = @event.CreatedAt
    };

  public OrderSummary Apply(OrderSummary currentData, OrderShipped @event) =>
    currentData with {
      Status = OrderStatus.Shipped,
      ShippedAt = @event.ShippedAt
    };
}

The generator automatically discovers OrderSummaryPerspective and generates registration code.

Combining with Other Registrations

Full Registration Setup

var builder = WebApplication.CreateBuilder(args);

// Database
builder.Services.AddDbContext<AppDbContext>(...);

// Core Whizbang (auto-registers discovered Perspectives and Lenses)
builder.Services.AddWhizbang();

// Perspective runners (for perspective materialization)
builder.Services.AddWhizbangPerspectives();

// Explicit generated registrations — only when bypassing AddWhizbang()
builder.Services.AddPerspectiveServices();
builder.Services.AddLensServices();         // Or use AddAllWhizbangServices()

See Also