Skip to main content
Version: Next

Domain Model Design

Files Referenced in this Document

Table of Contents​

  1. Introduction
  2. Aggregate Root Structure and Behavior
  3. Entity Field Definitions
  4. Audit Capability Inheritance
  5. Factory Method and Construction Logic
  6. Business Rule Validation Logic
  7. State Change Behavior
  8. Specification Pattern Application
  9. Domain Event Mechanism
  10. Event Handling Response
  11. Value Objects and Invariance Constraints
  12. Domain Service Boundaries
  13. UML Class Diagram Suggestion
  14. State Transition Diagram

Introduction​

This document detailedly describes the complete domain model of MyEntityName as a core aggregate root in Domain-Driven Design. This model embodies typical DDD practices, including key concepts such as aggregate roots, specification pattern, domain events, and repository interfaces. By analyzing its structure, behavior, and interaction relationships, it helps developers understand the core design principles and implementation methods of this domain.

Aggregate Root Structure and Behavior​

MyEntityName is the core aggregate root in the domain model, inheriting from FullAuditedAggregateRoot<Guid>, encapsulating business logic, data integrity, and behavioral rules. As an aggregate root, it is responsible for maintaining internal consistency and exposing mutable operations through clearly defined methods.

Section sources

Entity Field Definitions​

The MyEntityName aggregate root contains the following core fields, all ensured to be modified only through domain methods via protected set accessors:

  • Code: Code, string type, maximum length defined by MyEntityNameConsts.MaxCodeLength (default 64)
  • Name: Name, string type, maximum length defined by MyEntityNameConsts.MaxNameLength (default 64)
  • Sort: Sort, integer type, used for display sorting
  • Remark: Remark, string type, maximum length defined by MyEntityNameConsts.MaxRemarkLength (default 256)
  • IsDisabled: Is Disabled, nullable boolean type, indicating entity status

All fields use the virtual keyword to support EF Core's lazy loading and proxy features.

Section sources

Audit Capability Inheritance​

MyEntityName inherits from FullAuditedAggregateRoot<Guid>, automatically gaining complete audit capabilities, including:

  • CreationTime: Creation Time
  • CreatorId: Creator ID
  • LastModificationTime: Last Modification Time
  • LastModifierId: Last Modifier ID
  • IsDeleted: Is Deleted (Soft Delete)
  • DeleterId: Deleter ID
  • DeletionTime: Deletion Time

These audit fields are automatically managed by the framework, requiring no manual setting in business code, ensuring consistency and reliability of audit information.

Section sources

Factory Method and Construction Logic​

MyEntityName provides two construction methods:

  1. Protected Parameterless Constructor: Used by ORM framework for deserialization
  2. Public Parameterized Constructor: Acts as a factory method to create new instances, receiving necessary parameters like id, code, name, and performing basic validation

The construction process uses assertion methods like Check.NotNullOrWhiteSpace and Check.Length to ensure input data validity, reflecting the design principle of "establishing invariance at construction".

Section sources

Business Rule Validation Logic​

Business rule validation runs through the entire lifecycle, mainly reflected in:

  • Construction Validation: Ensure code and name are non-null and compliant in length
  • Update Validation: Re-validate code, name, and remark in Update method
  • Application Service Layer Validation: MyEntityNameAppService checks name uniqueness before creation/update
  • Import Validation: Check row-level data integrity and name duplication during batch import

Validation logic follows the "Fail Fast" principle, throwing meaningful exceptions immediately upon detecting violations.

Section sources

State Change Behavior​

MyEntityName supports the following state change operations:

  • Update: Update code, name, remark, and isDisabled fields
  • AdjustSort: Adjust sort value, supporting reordering logic
  • Clone: Clone entity, generating new ID and appending "_Copy" suffix

These methods are all implemented within the aggregate root, ensuring atomicity and consistency of state changes. Especially the AdjustSort method supports complex sorting adjustment logic, including moving up, moving down, and inserting at specified positions.

Section sources

Specification Pattern Application​

MyEntityNameSpecification implements the Specification Pattern, used to build reusable query conditions:

  • Purpose: Encapsulate complex query logic in the repository layer, improving code readability and testability
  • Implementation: Inherits from Volo.Abp.Specifications.Specification<T>, overrides ToExpression method
  • Parameterization: Supports dynamic construction of query conditions via name parameter
  • Composability: Can combine multiple specifications via And, Or operators

This specification is actually used in MyEntityNameAppService.GetListAsync to implement filtering by name.

Diagram sources

Section sources

Domain Event Mechanism​

MyEntityName publishes domain events via MyEntityNameEto (Event Transfer Object):

  • Event Definition: MyEntityNameEto contains Name property for passing event context
  • Event Publishing: Although current code does not show publishing logic, architecture is ready to publish events via IDistributedEventBus
  • Event Consumption: Supports distributed event processing, ensuring cross-service consistency

The domain event pattern decouples business logic from side-effect operations (like sending notifications, updating indexes).

Diagram sources

Section sources

Event Handling Response​

MyEntityNameEventHandler implements response to MyEntityNameEto events:

  • Implement Interface: Implement IDistributedEventHandler<MyEntityNameEto> and ITransientDependency
  • Processing Logic: Currently empty implementation (Task.CompletedTask), reserved as an extension point
  • Lifecycle: Transient dependency, new instance created for each event trigger

This handler can respond to events from other services in a distributed environment, implementing integration across bounded contexts.

Section sources

Value Objects and Invariance Constraints​

Value objects are not explicitly defined in this model, but value object design ideas are reflected:

  • Invariance Constraints: Centrally manage field length constraints via constant class MyEntityNameConsts
  • Clone Tag: MyEntityNameConsts.CloneTag defines suffix rules during cloning
  • Data Seed: MyEntityNameDataSeedContributor ensures test data consistency

These designs jointly maintain domain invariance rules.

Section sources

Domain Service Boundaries​

Domain service boundaries are clear, following layered architecture:

  • Domain Layer: MyEntityName, MyEntityNameSpecification, MyEntityNameEto
  • Repository Interface: IMyEntityNameRepository defines data access contract
  • Application Service: MyEntityNameAppService orchestrates domain objects, containing no core business rules
  • DTO Layer: MyEntityNameCreateDto, MyEntityNameUpdateDto used for data transfer

This layering ensures purity of the domain model, preventing business logic leakage to the application layer.

Diagram sources

UML Class Diagram Suggestion​

Diagram sources

State Transition Diagram​

Diagram sources