Domain invariants are conditions that must always hold true for an entity or value object to be in a valid state. Placing this validation inside the domain layer — rather than in application services, controllers, or validators — means the domain model is self-protecting: it is impossible to construct or mutate an aggregate into an illegal state, regardless of where the call originates. SharedKernel providesDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/jordiaragonzaragoza/JordiAragonZaragoza.SharedKernel/llms.txt
Use this file to discover all available pages before exploring further.
IBusinessRule, BusinessRuleValidationException, and the CheckRule static helper to make this pattern concise and consistent.
IBusinessRule
Every business rule is a class that implementsIBusinessRule:
| Member | Purpose |
|---|---|
Message | Human-readable description of the invariant, surfaced in the exception message when the rule is broken. |
IsBroken() | Returns true when the invariant is violated. Return false to indicate the rule is satisfied. |
BusinessRuleValidationException
When a rule is broken,CheckRule throws BusinessRuleValidationException, which wraps the offending rule:
brokenRule.Message. BrokenRule is available on the exception so that handlers (e.g. an exception middleware) can inspect which rule was violated and produce a structured error response.
CheckRule — the guard helper
CheckRule is a static helper present on BaseEntity<TId>, BaseValueObject, and BaseDomainService:
protected static, it is available in every concrete aggregate, entity, value object, and domain service without needing to inject anything.
Full example
Implementing IBusinessRule
Calling CheckRule inside an aggregate
Calling CheckRule inside a value object
Domain Exceptions
SharedKernel ships several domain exceptions beyondBusinessRuleValidationException. Each plays a distinct role:
BusinessRuleValidationException
BusinessRuleValidationException
Thrown by: Catch this in application-layer exception handlers to translate it into a
CheckRule(IBusinessRule rule) on BaseEntity, BaseValueObject, or BaseDomainService.When: A domain invariant expressed as an IBusinessRule is violated — for example, placing an order with no items.400 Bad Request or a validation error response.NotFoundException
NotFoundException
Thrown by: Repository or application-service logic when an entity cannot be located by its ID.When: A required aggregate or read-model record is missing from the data store.The
(name, key) overload produces the message "{name}: {key} not found.". Map this to a 404 Not Found in your exception middleware.InvalidAggregateStateException<TAggregate, TId>
InvalidAggregateStateException<TAggregate, TId>
Thrown by: Usage inside
EnsureValidState() inside an aggregate when a state transition would leave the aggregate in an inconsistent state.When: The post-event state of the aggregate fails an invariant that cannot be expressed as a simple pre-condition (e.g. cross-field constraints that only make sense after the event is applied).EnsureValidState:EventCannotBeAppliedToAggregateException<TAggregate, TId>
EventCannotBeAppliedToAggregateException<TAggregate, TId>
Thrown by: The Usage inside a
default case inside a When switch when an unrecognised event arrives.When: An event type is dispatched to an aggregate that has no handler for it — typically a sign of a configuration error or a mismatch between aggregate and event-store stream.When switch: