Validation with read models
Arc’s validation model — data annotations, ConceptValidator<T>, and CommandValidator<TCommand> — works unchanged when Chronicle is in the picture. What the integration adds is one thing: a validator can take the read model Chronicle projected for the command’s key as a constructor dependency, and validate against current state without a query.
public class SettleLedgerValidator : CommandValidator<SettleLedger>{ public SettleLedgerValidator(LedgerBalance balance) => RuleFor(command => command.LedgerId) .Must(_ => balance.Balance > 0) .WithMessage("Ledger has no funds to settle.");}Arc resolves LedgerBalance for the same event source id the command appends events to, then constructs the validator with it. The flow is:
- The command is bound, and its event source id is resolved — from
[Key], from a property that converts toEventSourceId, or fromICanProvideEventSourceId. See Resolving EventSourceId, which contributes the value to the Command Context Values. - The read model instance is loaded from Chronicle’s read model store by that id.
- Validators are constructed with it and their rules run — before
Handle()is invoked.
Because the same command scope serves Provide() and Handle(), all three see the same instance.
What to be aware of
Section titled “What to be aware of”- A key does not prove existence. Declare the parameter nullable when a missing projection is a business condition, non-nullable when it is required. This is the central decision — see nullable versus required.
- Read models are eventually consistent. They are the right input for gating on projected state, and the wrong one for an invariant that must hold under concurrent commands. Use a Chronicle constraint for those.
- Validators need the Arc command pipeline. Read-model injection does not work through MVC controllers — see
ReadModelValidatorRequiresCommandPipeline.
See also
Section titled “See also”- Use current state in a command — the recipe, covering validators,
Provide(), andHandle(). - Read models in commands — the full reference for all three positions.
- Command validation — Arc’s validation model in general.