CoreEx.DomainDriven 4.0.0-preview-1

This is a prerelease version of CoreEx.DomainDriven.
dotnet add package CoreEx.DomainDriven --version 4.0.0-preview-1
                    
NuGet\Install-Package CoreEx.DomainDriven -Version 4.0.0-preview-1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CoreEx.DomainDriven" Version="4.0.0-preview-1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CoreEx.DomainDriven" Version="4.0.0-preview-1" />
                    
Directory.Packages.props
<PackageReference Include="CoreEx.DomainDriven" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CoreEx.DomainDriven --version 4.0.0-preview-1
                    
#r "nuget: CoreEx.DomainDriven, 4.0.0-preview-1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CoreEx.DomainDriven@4.0.0-preview-1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CoreEx.DomainDriven&version=4.0.0-preview-1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=CoreEx.DomainDriven&version=4.0.0-preview-1&prerelease
                    
Install as a Cake Tool

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 (Equals considers Id only) 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, and ModifyAndMakeReadOnly<TResult> wrappers enforce CheckReadOnly and OnCheckCanMutate before any state change, then advance PersistenceState automatically and fire the Mutated event.
  • 🔒 Read-only enforcement: MakeReadOnly() / IsReadOnly locks an entity after hydration or after terminal mutations; all Modify/Remove paths throw InvalidOperationException when violated.
  • 📢 Aggregate root with integration events: Aggregate<TId, TSelf> adds AddEvent(EventData) / ClearEvents() and the Events / HasEvents members for transient integration-event accumulation inside a unit-of-work scope.
  • 🔧 Override hooks: OnCheckCanMutate() returns a Result for pre-mutation business-rule validation; OnMutate() is a post-mutation extension point; both are called inside every Modify/Remove wrapper.
  • 💧 Hydration helpers: SetChangeLog, SetETag, and SetPersistenceState bypass read-only and state-change logic by design, allowing infrastructure layers to rehydrate an entity from persistence without triggering mutation semantics.
  • 🔑 CompositeKey support: EntityKey exposes the entity identity as a CompositeKey for infrastructure layers that need a key independent of the typed Id.

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.Events and 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.

  • CoreEx - Provides IIdentifier, IChangeLog, IETag, CompositeKey, EventData, and Result<T> consumed by the DDD types.
  • CoreEx.EntityFrameworkCore - Persists Entity<TId, TSelf> and Aggregate<TId, TSelf> via EfDbModel<TModel>; uses PersistenceState to determine insert/update/delete operations.
  • CoreEx.Validation - Validates entity state; OnCheckCanMutate can 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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 42 6/20/2026