CHR0004: Reactor method has a parameter that cannot be resolved
Rule Description
Section titled “Rule Description”A reactor handler method takes the event it reacts to as its first parameter. Any further parameters are resolved as dependencies when the method is invoked:
- The
EventContextfor the triggering event. - A read model — a type that has a reducer or projection. It is materialized strongly consistent from that reducer or projection.
- A service resolved from the service provider.
A parameter that is a primitive, value type, or string can never be a read model and is almost never a service, so it is flagged: at runtime it would fail to resolve and the partition would fail.
Severity
Section titled “Severity”Warning
Allowed Signatures
Section titled “Allowed Signatures”using Cratis.Chronicle.Events;
public interface ValidReactorMethodSignatures<TEvent, TReadModel, IService>{ void MethodName(TEvent @event); Task MethodNameAsync(TEvent @event);
void MethodName(TEvent @event, EventContext context); Task MethodNameAsync(TEvent @event, EventContext context);
Task MethodNameAsync(TEvent @event, EventContext context, TReadModel readModel, IService service); Task MethodNameAsync(TEvent @event, TReadModel readModel);}Where TEvent is a type marked with [EventType], and TReadModel is a type that has a reducer or projection.
Example
Section titled “Example”Violation
Section titled “Violation”using Cratis.Chronicle.Events;using Cratis.Chronicle.Reactors;
[EventType]public record Chr0004OrderUpdated;
public class InvalidOrderReactor : IReactor{ public Task OrderUpdated(Chr0004OrderUpdated @event, int count) => Task.CompletedTask;}using Cratis.Chronicle.Events;using Cratis.Chronicle.Reactors;
[EventType]public record Chr0004FixedOrderUpdated;
public record Chr0004Order(int Count);
public class ValidOrderReactor : IReactor{ public Task OrderUpdated(Chr0004FixedOrderUpdated @event, Chr0004Order order) => Task.CompletedTask;}Why This Rule Exists
Section titled “Why This Rule Exists”Reactors take dependencies on their handler methods. Read models are resolved directly by Chronicle, and other dependencies come from the service provider. A primitive, value type, or string is neither, so flagging it early prevents a runtime resolution failure that would pause the event source partition.