Declarative constraints
The declarative API lets you define constraints in a dedicated class by implementing IConstraint. Chronicle discovers all IConstraint implementations automatically — no registration is needed.
Use declarative constraints when you need:
- Uniqueness spanning multiple event types with different property names
- A callback to compose dynamic violation messages
- More explicit control over constraint names
Constraint types
Section titled “Constraint types”| Type | Description |
|---|---|
| Unique property | Enforce that a property value is unique across one or more event types |
| Unique event type | Enforce that only one event of a specific type can be appended per event source |
Defining a constraint
Section titled “Defining a constraint”Implement IConstraint and call the builder in Define:
using Cratis.Chronicle.Events;using Cratis.Chronicle.Events.Constraints;
[EventType]public record ConstraintsDeclarativeIndexProjectCreated(string Name);
[EventType]public record ConstraintsDeclarativeIndexProjectRemoved;
public class ConstraintsDeclarativeIndexUniqueProjectName : IConstraint{ public void Define(IConstraintBuilder builder) => builder.Unique(unique => unique .On<ConstraintsDeclarativeIndexProjectCreated>(e => e.Name) .RemovedWith<ConstraintsDeclarativeIndexProjectRemoved>());}Kotlin does not support this workflow yet.Java does not support this workflow yet.import { constraint, eventType, IConstraint, IConstraintBuilder } from '@cratis/chronicle';
@eventType()class ConstraintsDeclarativeIndexProjectCreated { constructor(readonly name: string) {}}
@eventType()class ConstraintsDeclarativeIndexProjectRemoved {}
@constraint()class ConstraintsDeclarativeIndexUniqueProjectName implements IConstraint { define(builder: IConstraintBuilder): void { builder.unique(unique => unique .on(ConstraintsDeclarativeIndexProjectCreated, e => e.name) .removedWith(ConstraintsDeclarativeIndexProjectRemoved)); }}Discovery
Section titled “Discovery”Chronicle scans all loaded assemblies for types that implement IConstraint and registers them with the Kernel automatically when the client starts. No explicit registration is required.