Skip to content

Simple projection

A projection in Cratis is a way to create read models from events in the event store. The simplest projection automatically maps event properties to read model properties with matching names using the default AutoMap behavior.

A projection implements IProjectionFor<TReadModel> and defines its behavior in the Define method:

using Cratis.Chronicle.Projections;
public class DecSimpleUserProjection : IProjectionFor<DecSimpleUser>
{
public void Define(IProjectionBuilderFor<DecSimpleUser> builder) => builder
.From<DecSimpleUserCreated>();
}

View C# snippet source on GitHub

This projection:

  • Automatically maps properties from UserCreated event to the User read model (AutoMap is enabled by default)
  • Uses the event source ID as the key for the read model
  • Properties with matching names are automatically mapped

Note: AutoMap is enabled by default at the top level. You don’t need to call .AutoMap() explicitly unless you want to ensure it’s enabled in contexts where it might be disabled. Read more about auto mapping

From<TEvent>() also accepts a base event type or an interface. It registers every known event type assignable to TEvent, including the base type itself when it is an event type. The same property mappings, key, and parent key apply to each event type, whether the registration is at the root, in a children collection, or in a nested object.

When a base or interface registration overlaps an explicit From<ConcreteEvent>(), their property mappings are combined. The explicit registration wins on conflicting properties and supplies the key and parent key, regardless of call order. Without an explicit registration, the first matching base or interface registration supplies the keys, while later inherited mappings win on conflicting properties. This does not subscribe to unrelated event types; use FromAll for that behavior.

The read model is a simple record or class representing the projected data:

public record DecSimpleUser(string Name, string Email, DateTimeOffset CreatedAt);

View C# snippet source on GitHub

The event should match the read model structure for auto-mapping to work:

using Cratis.Chronicle.Events;
[EventType]
public record DecSimpleUserCreated(string Name, string Email, DateTimeOffset CreatedAt);

View C# snippet source on GitHub

When a UserCreated event is appended to the event log:

  1. The projection automatically creates or updates a User read model
  2. The event source ID becomes the key for the read model
  3. Properties with matching names are copied from event to read model
  4. The read model is stored and can be queried

Auto-mapping works when property names and types match between the event and read model. For more control over the mapping, see projection with custom properties.