Layers : Domain

The Domain layer templates generate the complete Domain-Driven Design (DDD) implementation for each entity within a bounded context. The generator produces entities with factory methods, domain events, domain errors, repository and service contracts, FluentValidation validators, and localization resources — all driven by the entity definitions configured in the Scaffolder.net UI.

Project File

The {{Solution.Name}}.Domain.{{BoundedContext.Name}}.csproj file defines the domain project with references to the Shared.Core and Shared.Domain projects, providing access to the Result pattern, Error types, domain abstractions, and validation extensions.

Assembly Reference

The {{Solution.Name}}Domain{{BoundedContext.Name}}AssemblyReference class is a sealed marker class used to reference the domain assembly for reflection-based service registration and dependency injection scanning.

Global Usings

The GlobalUsings.cs file is generated with global using directives for all entity namespaces within the bounded context, including entities, errors, events (if enabled), repositories, services, validators, and resources. This eliminates the need for explicit using statements throughout the domain project.

Entities

For each entity, the generator produces a sealed entity class inheriting from Entity<TEntityId>. The class includes :
  • Properties : Scalar properties (with private set), navigation properties for foreign keys, and collection properties for one-to-many relationships. Non-nullable strings are initialized to null!.
  • CreateAsync : A static factory method that constructs the entity, runs FluentValidation, checks uniqueness constraints (Id and unique properties) via the domain service, and raises a CreatedDomainEvent if domain events are enabled.
  • EditAsync : An instance method that validates the updated values, checks uniqueness constraints excluding the current Id, applies the new property values, and raises an EditedDomainEvent if domain events are enabled.
  • Delete : An instance method that raises a DeletedDomainEvent if domain events are enabled and returns a success result.

Domain Errors

The {{Entity.NameSingular}}DomainError static class contains nested sealed error classes for each uniqueness constraint. If the Id is not auto-generated, an IdAlreadyExists error is generated. For each unique property, a {{PropertyName}}AlreadyExists error is generated. Each error accepts a string localizer and the conflicting value, producing a localized error message with ErrorTypeEnum.BusinessRule.

Domain Events

When the GenerateDomainEvents option is enabled for an entity, the generator creates three sealed record types implementing IDomainEvent :
  • {{Entity.NameSingular}}CreatedDomainEvent : Carries the entity's Id and all property values when a new entity is created.
  • {{Entity.NameSingular}}DeletedDomainEvent : Carries the entity's Id and all property values when an entity is deleted.
  • {{Entity.NameSingular}}EditedDomainEvent : Carries the entity's Id and all property values when an entity is edited.

Domain Repository Interface

The I{{Entity.NameSingular}}DomainRepository interface extends IDomainRepository and defines data access methods for uniqueness checks. If the Id is not auto-generated, an ExistsWithIdAsync method is generated. For each unique property, ExistsWith{{PropertyName}}Async and ExistsWith{{PropertyName}}ExcludingIdAsync methods are generated.

Domain Service

The domain service is split into a sealed implementation and an interface :
  • {{Entity.NameSingular}}DomainService : A sealed implementation that injects the domain repository and a string localizer. Each Ensure* method queries the repository for existing values and returns a Result.Fail with the corresponding domain error if a conflict is found, or Result.Ok if the value is unique.
  • I{{Entity.NameSingular}}DomainService : An interface extending IDomainService that defines EnsureIdIsUniqueForCreateAsync (if Id is not auto-generated) and Ensure{{PropertyName}}IsUniqueForCreateAsync / Ensure{{PropertyName}}IsUniqueForEditAsync for each unique property.

Entity Validator

The {{Entity.NameSingular}}EntityValidator is an internal sealed FluentValidation AbstractValidator that validates the entity before creation and edition. The generator produces validation rules based on each property's type and constraints :
  • String : MinimumLength and MaximumLength rules if configured.
  • Numeric types (Byte, Decimal, Double, Float, Int, Long, Short) : GreaterThanOrEqualTo and LessThanOrEqualTo rules using configured min/max values or type-specific bounds.
  • Nullable Short : Must rules that allow null values while enforcing min/max constraints on non-null values.

Resources

The {{Solution.Name}}Domain{{BoundedContext.Name}}Resource class and its associated .resx file provide localized strings for the domain layer. The generator populates the .resx with :
  • Property display names (e.g., {{Entity.NameSingular}}Entity.Id, {{Entity.NameSingular}}Entity.{{PropertyName}}) using humanized names.
  • Uniqueness error messages (e.g., {{Entity.NameSingular}}DomainError.IdAlreadyExists, {{Entity.NameSingular}}DomainError.{{PropertyName}}AlreadyExists) with parameterized values for the conflicting data.

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please reload the page.