CoreEx.DomainDriven
4.0.0-preview-1
dotnet add package CoreEx.DomainDriven --version 4.0.0-preview-1
NuGet\Install-Package CoreEx.DomainDriven -Version 4.0.0-preview-1
<PackageReference Include="CoreEx.DomainDriven" Version="4.0.0-preview-1" />
<PackageVersion Include="CoreEx.DomainDriven" Version="4.0.0-preview-1" />
<PackageReference Include="CoreEx.DomainDriven" />
paket add CoreEx.DomainDriven --version 4.0.0-preview-1
#r "nuget: CoreEx.DomainDriven, 4.0.0-preview-1"
#:package CoreEx.DomainDriven@4.0.0-preview-1
#addin nuget:?package=CoreEx.DomainDriven&version=4.0.0-preview-1&prerelease
#tool nuget:?package=CoreEx.DomainDriven&version=4.0.0-preview-1&prerelease
CoreEx.DomainDriven
Provides the foundational Domain-Driven Design (DDD) building blocks for CoreEx: typed entities, aggregate roots with integration-event support, persistence-state tracking, and mutation-guard helpers.
Overview
CoreEx.DomainDriven implements the core DDD concepts referenced throughout the CoreEx framework. It supplies base classes and interfaces for entities and aggregate roots that are identity-based, change-tracked, and mutation-guarded, integrating cleanly with CoreEx contracts (IIdentifier, IChangeLog, IETag) and the broader Result<T> pipeline.
The package intentionally stays minimal: it does not dictate a persistence strategy, an ORM, or an event bus. Instead it establishes the behavioural invariants — read-only enforcement, persistence state transitions, event accumulation — that the application and infrastructure layers rely on. Higher-level packages such as CoreEx.EntityFrameworkCore and CoreEx.Database consume these contracts when mapping and persisting domain objects.
Key capabilities
- 🆔 Typed entity base:
Entity<TId, TSelf>enforces identity-based equality (EqualsconsidersIdonly) and carries a fluent self-typed API for state manipulation. - 🔄 Persistence state machine:
PersistenceState(Unknown → New / NotModified → Modified → Removed) with extension helpers (IsNew,IsModified,IsNewOrModified,IsRemoved, …) and validated one-way transitions that prevent illegal state changes. - 🛡 Mutation guards:
Modify(action),Remove(action),ModifyAndMakeReadOnly, andModifyAndMakeReadOnly<TResult>wrappers enforceCheckReadOnlyandOnCheckCanMutatebefore any state change, then advancePersistenceStateautomatically and fire theMutatedevent. - 🔒 Read-only enforcement:
MakeReadOnly()/IsReadOnlylocks an entity after hydration or after terminal mutations; allModify/Removepaths throwInvalidOperationExceptionwhen violated. - 📢 Aggregate root with integration events:
Aggregate<TId, TSelf>addsAddEvent(EventData)/ClearEvents()and theEvents/HasEventsmembers for transient integration-event accumulation inside a unit-of-work scope. - 🔧 Override hooks:
OnCheckCanMutate()returns aResultfor pre-mutation business-rule validation;OnMutate()is a post-mutation extension point; both are called inside everyModify/Removewrapper. - 💧 Hydration helpers:
SetChangeLog,SetETag, andSetPersistenceStatebypass read-only and state-change logic by design, allowing infrastructure layers to rehydrate an entity from persistence without triggering mutation semantics. - 🔑 CompositeKey support:
EntityKeyexposes the entity identity as aCompositeKeyfor infrastructure layers that need a key independent of the typedId.
Key types
| Type | Description |
|---|---|
IEntity |
Core DDD entity contract: PersistenceState, IsReadOnly, IReadOnlyIdentifier, IReadOnlyChangeLog, IReadOnlyETag. |
IAggregateRoot |
Extends IEntity with Events (read-only collection of EventData) and HasEvents; integration events only — domain events are not supported by design. |
EntityBase |
Abstract base implementing IEntity; provides the full mutation-guard (Modify, Remove), read-only, state-machine, SetChangeLog/SetETag hydration, Mutated event, and OnCheckCanMutate/OnMutate hooks. |
Entity<TId, TSelf> |
Abstract typed, self-referential entity (TSelf pattern) with identity-based equality; re-exposes SetPersistenceState, AsNew, AsNotModified, MakeReadOnly, SetChangeLog, and SetETag as fluent TSelf-returning methods. |
Aggregate<TId, TSelf> |
Extends Entity<TId, TSelf> with AddEvent(EventData) / ClearEvents() for integration-event accumulation within the aggregate lifetime. |
PersistenceState |
Enum: Unknown, New, NotModified, Modified, Removed; governs the entity lifecycle from creation through persistence to deletion. |
DomainDrivenExtensions |
Extension methods on PersistenceState: IsNew, IsNotModified, IsModified, IsRemoved, IsNotRemoved, IsNewOrModified. |
Domain Events — Intentionally Not Supported
CoreEx deliberately does not provide a native domain-event mechanism (e.g. MediatR INotification dispatch or an in-process event bus). This is a conscious architectural decision:
- Chatty emission — fine-grained domain events (
PropertyChanged,ItemAdded, etc.) generate high volumes of events that produce implicit, hard-to-trace side-effects throughout the application layer. - Non-explicit side-effects — handler chains driven by in-process events obscure control flow, making it difficult to reason about what happens as a result of a single aggregate mutation.
- Integration events are sufficient — coarse-grained integration events via
IUnitOfWork.Eventsand the transactional outbox communicate meaningful state changes to other systems in an explicit, auditable, and transactional way.
A developer can extend CoreEx with a domain-event mechanism if a genuine use case exists — for example, by raising events from aggregate mutations and dispatching them via MediatR after the transaction commits. This is an opt-in extension, not a framework default.
Related namespaces
CoreEx- ProvidesIIdentifier,IChangeLog,IETag,CompositeKey,EventData, andResult<T>consumed by the DDD types.CoreEx.EntityFrameworkCore- PersistsEntity<TId, TSelf>andAggregate<TId, TSelf>viaEfDbModel<TModel>; usesPersistenceStateto determine insert/update/delete operations.CoreEx.Validation- Validates entity state;OnCheckCanMutatecan delegate to a CoreEx validator for pre-mutation rule checks.
AI Usage Guide
An AGENTS.md file is included with this package. AI coding assistants (GitHub Copilot, Claude, Cursor, etc.) that support workspace-injected package documentation will automatically surface concise usage guidance, code examples, and Do Not rules for this package without requiring a local CoreEx checkout.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- CoreEx (>= 4.0.0-preview-1)
- CoreEx.Events (>= 4.0.0-preview-1)
-
net8.0
- CoreEx (>= 4.0.0-preview-1)
- CoreEx.Events (>= 4.0.0-preview-1)
-
net9.0
- CoreEx (>= 4.0.0-preview-1)
- CoreEx.Events (>= 4.0.0-preview-1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.0.0-preview-1 | 43 | 6/20/2026 |