Skip to content

Filter reducers and reactors by event source type

Use [EventSourceType] on a reducer or reactor when it should only handle events appended with a specific event source type.

Chronicle compares the observer attribute to the eventSourceType: value used when appending the event. If the values do not match, the reducer or reactor is skipped.

using Cratis.Chronicle.Events;
using Cratis.Chronicle.EventSequences;
using Cratis.Chronicle.Reactors;
[EventType]
public record FilterBySourceTypeCustomerRegistered(string EmailAddress);
public class FilterBySourceTypeCustomerRegistrationService(IEventLog eventLog)
{
public Task Register(string emailAddress) =>
eventLog.Append(
EventSourceId.New(),
new FilterBySourceTypeCustomerRegistered(emailAddress),
eventSourceType: "customer");
}
[EventSourceType("customer")]
public class FilterBySourceTypeCustomerWelcomeReactor : IReactor
{
public Task Registered(FilterBySourceTypeCustomerRegistered @event, EventContext context) => Task.CompletedTask;
}

The reactor is only invoked for events appended with eventSourceType: "customer".

using Cratis.Chronicle.Events;
using Cratis.Chronicle.EventSequences;
using Cratis.Chronicle.Reducers;
[EventType]
public record FilterBySourceTypeInvoiceIssued(decimal Amount);
public record FilterBySourceTypeCustomerInvoiceTotal(decimal Amount);
[EventSourceType("customer")]
public class FilterBySourceTypeCustomerInvoiceTotalReducer : IReducerFor<FilterBySourceTypeCustomerInvoiceTotal>
{
public FilterBySourceTypeCustomerInvoiceTotal Issued(FilterBySourceTypeInvoiceIssued @event, FilterBySourceTypeCustomerInvoiceTotal? current, EventContext context) =>
new((current?.Amount ?? 0m) + @event.Amount);
}
public class FilterBySourceTypeInvoicingService(IEventLog eventLog)
{
public Task IssueCustomerInvoice(decimal amount) =>
eventLog.Append(
EventSourceId.New(),
new FilterBySourceTypeInvoiceIssued(amount),
eventSourceType: "customer");
}

If you append the same event with eventSourceType: "supplier", this reducer does not receive it.

You can combine [EventSourceType] with [FilterEventsByTag] or [EventStreamType]. When you do, Chronicle requires all configured filter categories to match.