Skip to content

CHR0015: Projection must not have side effects

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.

Error

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>(_ => _);
}

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.

  • CHR0016: Projection Define() must not contain imperative code
  • CHR0017: Constraint must not have side effects