Filter reducers and reactors by tag
Use [FilterEventsByTag] when a reducer or reactor should only handle events that carry specific tags.
What counts as a matching tag
Section titled “What counts as a matching tag”Chronicle compares the filter tag against the tags on the appended event. Those tags can come from:
[Tag]or[Tags]on the event type- The
tags:argument when you append the event
[Tag] and [Tags] on the reducer or reactor do not filter anything. They only label the observer itself.
Filter a reactor by tag
Section titled “Filter a reactor by tag”using Cratis.Chronicle;using Cratis.Chronicle.Events;using Cratis.Chronicle.EventSequences;using Cratis.Chronicle.Reactors;
[EventType][Tag("customer-lifecycle")]public record FilterByTagCustomerRegistered(string EmailAddress);
public class FilterByTagCustomerRegistrationService(IEventLog eventLog){ public Task Register(string emailAddress) => eventLog.Append( EventSourceId.New(), new FilterByTagCustomerRegistered(emailAddress), tags: ["vip", "onboarding"]);}
[FilterEventsByTag("vip")]public class FilterByTagVipWelcomeReactor : IReactor{ public Task Registered(FilterByTagCustomerRegistered @event, EventContext context) => Task.CompletedTask;}The reactor receives the event because the append call added the vip tag.
Filter a reducer by tag
Section titled “Filter a reducer by tag”using Cratis.Chronicle;using Cratis.Chronicle.Events;using Cratis.Chronicle.EventSequences;using Cratis.Chronicle.Reducers;
[EventType]public record FilterByTagOrderPlaced(decimal TotalAmount);
public record FilterByTagPriorityOrderTotals(decimal TotalAmount);
[FilterEventsByTag("priority")]public class FilterByTagPriorityOrderTotalsReducer : IReducerFor<FilterByTagPriorityOrderTotals>{ public FilterByTagPriorityOrderTotals Placed(FilterByTagOrderPlaced @event, FilterByTagPriorityOrderTotals? current, EventContext context) => new((current?.TotalAmount ?? 0m) + @event.TotalAmount);}
public class FilterByTagCheckoutService(IEventLog eventLog){ public Task PlacePriorityOrder(decimal totalAmount) => eventLog.Append( EventSourceId.New(), new FilterByTagOrderPlaced(totalAmount), tags: ["priority"]);}The reducer only updates when the appended event carries the priority tag.
Use multiple filter tags
Section titled “Use multiple filter tags”Multiple [FilterEventsByTag] attributes widen the match:
using Cratis.Chronicle.Events;using Cratis.Chronicle.Reactors;
[EventType]public record FilterByTagMultiCustomerRegistered(string EmailAddress);
[FilterEventsByTag("vip")][FilterEventsByTag("priority")]public class FilterByTagMultiPriorityNotificationsReactor : IReactor{ public Task Registered(FilterByTagMultiCustomerRegistered @event) => Task.CompletedTask;}Chronicle dispatches the event if it has either vip or priority.