Skip to content

Value Objects

Value Object is another kind of domain object that is identified by its properties rather than a unique Id. That means two Value Objects with same properties are considered as the same object.

If a concept has no meaningful identity outside of its parent entity and is not shared by multiple entities, it should not have its own unique identifier. In such cases, it is a strong candidate to be modeled as a Value Object.

  • Do define value objects in the domain layer.
  • Do drive your class from ValueRecordObject abstract record. This base class available at GridLab.Abp.Ddd.Domain package.

Primary Constructor

Value objects are generally implemented as immutable and mostly are much simpler than the Entities.

  • Do define a primary constructor that ensures the validity of the entity on creation. Primary constructors are used to create a new instance of the entity by the application code.

  • Do define primary constructor as public, internal or protected internal based on the requirements. If it's not public, the entity is expected to be created by a domain service.

  • Do implement Value Objects using a record type. Its built-in init properties offer the ideal combination of immutability and simplicity.

    public record Address : ValueRecordObject
    {
        public required string Line1 { get; init; }
        public string? Line2 { get; init; }
        public required string City { get; init; }
        public required string Country { get; init; }
        public required string PostCode { get; init; }
    }
    

Parameterless Constructor

  • Do always define a protected parameterless constructor to be compatible with ORMs.

Other Class Members

  • Do always define properties and methods as virtual (except private methods, obviously). Because some ORMs and dynamic proxy tools require it.