CHR0015: Projection must not have side effects
Rule Description
Section titled “Rule Description”A class implementing IProjectionFor<T> must not inject ICommandPipeline or IEventLog via its constructor. Projections are pure state builders that derive read models from events and must not produce side effects.
Severity
Section titled “Severity”Error
Example
Section titled “Example”Violation
Section titled “Violation”using Cratis.Chronicle.EventSequences;using Cratis.Chronicle.Projections;
public class UserReadModel { }
public class UserProjection : IProjectionFor<UserReadModel>{ readonly IEventLog _eventLog;
public UserProjection(IEventLog eventLog) { _eventLog = eventLog; }
public void Define(IProjectionBuilderFor<UserReadModel> builder) => builder.From<UserRegistered>(_ => _);}using Cratis.Chronicle.Projections;
public class UserReadModel { }
public class UserProjection : IProjectionFor<UserReadModel>{ public void Define(IProjectionBuilderFor<UserReadModel> builder) => builder.From<UserRegistered>(_ => _);}Why This Rule Exists
Section titled “Why This Rule Exists”Projections declare how to build a read model from a stream of events. They are evaluated at replay time and must be purely declarative. Injecting IEventLog or ICommandPipeline implies intent to perform side effects during projection evaluation, which breaks idempotency and replay safety.