Skip to content

The search box knows all the secrets -- try it!

Polecat is part of the Critter Stack ecosystem.

JasperFx Logo JasperFx provides formal support for Polecat and other Critter Stack libraries. Please check our Support Plans for more details.

Projections Overview ​

Projections are the mechanism for building read models from events. Polecat supports several projection types and lifecycle strategies.

Projection Lifecycle ​

Every projection runs with one of three lifecycle strategies:

Inline ​

Projections run in the same transaction as the event append. This provides strong consistency -- the read model is always up to date:

cs
opts.Projections.Add<SingleStreamProjection<OrderSummary, Guid>>(ProjectionLifecycle.Inline);

Async ​

Projections run in the background via the async daemon. The read model is eventually consistent:

cs
opts.Projections.Add<SingleStreamProjection<OrderSummary, Guid>>(ProjectionLifecycle.Async);

Live ​

Projections are built on demand by replaying events each time. No read model is persisted:

cs
var order = await session.Events.AggregateStreamAsync<OrderSummary>(streamId);

Projection Types ​

TypeDescriptionUse Case
Single StreamOne aggregate per streamOrder, Invoice, Account
Multi StreamAggregate across multiple streamsDashboard, Report
Event ProjectionPer-event document creationAudit log, Search index
Flat TableDirect SQL table writesReporting, Analytics
CompositeMulti-stage orchestrationComplex pipelines

Conventional Projection Methods ​

Polecat discovers projection methods by convention:

Create ​

Creates the initial aggregate from a stream-starting event:

cs
public static OrderSummary Create(OrderCreated e) =>
    new() { Status = "Created", Amount = e.Amount };

Apply ​

Applies an event to an existing aggregate:

cs
public void Apply(OrderShipped e)
{
    Status = "Shipped";
    ShippedDate = e.ShippedAt;
}

ShouldDelete ​

Signals that the aggregate should be deleted:

cs
public bool ShouldDelete(OrderCancelled e) => true;

Registration ​

cs
var store = DocumentStore.For(opts =>
{
    opts.Connection("...");

    // Single stream projection (inline)
    opts.Projections.Add<SingleStreamProjection<OrderSummary, Guid>>(ProjectionLifecycle.Inline);

    // Multi stream projection as async
    opts.Projections.Add<DashboardProjection>(ProjectionLifecycle.Async);

    // Event projection
    opts.Projections.Add<AuditLogProjection>(ProjectionLifecycle.Inline);
});

Released under the MIT License.