Value Objects explained

I’ve already written about base entity class. Today, I’d like to continue with Value Object base class I use in my projects. Also, I’ll share some best practices regarding Value Objects implementation.

Value Objects: what is it?

“An object that represents a descriptive aspect of the domain with no conceptual identity is called a Value Object. Value Objects are instantiated to represent elements of the design that we care about only for what they are, not who or which they are.” [Eric Evans]

In other words, value objects don’t have their own identity. That is, we don’t care if a value object is the same physical object we had before or another one with the same set of properties. Value Objects are completely interchangeable.

For example, a dime coin would most likely represent a value object. It doesn’t matter what exact piece of metal you have, they all are just 10 cent coins. On the other hand, you may build a system which responsibility is to track every coin produced by a mint. In this case, you do care about which coin a person has because all of them have a unique identity.

Consequently, whether a class is a value object is dictated by your domain and use cases.

Attributes of Value Objects

Let’s specify attributes pertain to Value Objects.

  • No identity. A corollary of value objects’ identity-less nature is, obviously, not having an Id property. Unlike entities, value objects should be compared by value, not by identity field.
  • Immutability. As any value object can be replaced by another value object with the same property set, it’s a good idea to make them immutable to simplify working with them, especially in multithread scenarios. Instead of changing an existing value object, just create a new one.
  • Lifetime shortening. It’s another corollary of the value objects’ identity-less nature. They can’t exist without a parent entity owning them. In other words, there always must be a composition relationship between a Value Object class and an Entity class. Without it, value objects don’t make any sense.
  • Lifetime shortening leads to another consequence: Value Objects should not have separate tables in database. This one is an attribute programmers find the most controversial.

Developers, especially if they have wide experience with relational databases, tend to store Value Objects in separate tables (or, in case of NoSQL databases, in separate collections). Situation gets worse if there are more than one Entity class owning a Value Object.

For example, both Company and User entities might have a property referring to Address value object. The very first impulse could be extracting the fields concerning Address from Company and User tables to a separate Address table and storing references to it instead. I consider this approach as a bad practice. Not only does it make composition relationship more complex as you have to maintain consistency of two tables instead of one, but also gives developers a false assumption about the Address’s nature. As the Address table must have an Id column, it’s easy to mistake it for an Entity, despite its sole purpose of being a Value Object.

Give me the code!

There’s an implementation for Value Object base class made by Jimmy Bogard I often see developers copy. In short, it allows you to extract equality logic to the base class so that you don’t have to implement it in each Value Object separately. Its Equals() and GetHashCode() methods use reflection to gather information about the fields of a type and perform comparison or object’s hash code calculation.

Although this implementation might be a good solution for a quick scaffolding, it suffers from a fundamental flaw. Equality logic implementation should be a conscious decision. Every Value Object has its own unique property set and comparison strategy. By extracting this logic to a base class, you actually say that all Value Objects are just bags of data with the same behavior, which is not true. It’s worth nothing for a Value Object to have properties that don’t take part in equality logic. It’s too easy to forget to override Equals() and GetHashCode() in such cases.

Well, what should it look like then? Here’s the code I use in my projects:

public abstract class ValueObject<T>

    where T : ValueObject<T>


    public override bool Equals(object obj)


        var valueObject = obj as T;


        if (ReferenceEquals(valueObject, null))

            return false;


        return EqualsCore(valueObject);



    protected abstract bool EqualsCore(T other);


    public override int GetHashCode()


        return GetHashCodeCore();



    protected abstract int GetHashCodeCore();


    public static bool operator ==(ValueObject<T> a, ValueObject<T> b)


        if (ReferenceEquals(a, null) && ReferenceEquals(b, null))

            return true;


        if (ReferenceEquals(a, null) || ReferenceEquals(b, null))

            return false;


        return a.Equals(b);



    public static bool operator !=(ValueObject<T> a, ValueObject<T> b)


        return !(a == b);



Note that there’s no Id property because, as discussed earlier, Value Objects don’t have their own identity. Also, you might notice that the class doesn’t implement IEquatable<> interface. Instead, EqualsCore() is introduced. With IEquatable, you will have to write null-checking code both in Equals(object obj) and Equals(T obj) methods. Moreover, as Equals(T obj) is made abstract, you will have to copy null checks to all of the ValueObject’s subclasses. By making EqualsCore protected, you can get rid of such checks; all you should do is extract them to the Equals method of your base class.

Let’s take a look at how Address value object could be implemented:

public class Address : ValueObject<Address>


    public virtual string Street { get; protected set; }

    public virtual int ZipCode { get; protected set; }

    public virtual string Comment { get; protected set; }


    public Address(string street, int zipCode, string comment)




        Street = street;

        ZipCode = zipCode;

        Comment = comment;



    protected override bool EqualsCore(Address other)


        return Street == other.Street && ZipCode == other.ZipCode;



    protected override int GetHashCodeCore()


        return (ZipCode.GetHashCode() * 397) ^ Street.GetHashCode();



As you can see, Comment property doesn’t participate in EqualsCore() and GetHashCodeCore() methods because it’s just a user-created note; it can’t affect equality of addresses.

Also, note that properties are made read-only to comply with immutability requirement.

Value Objects and .NET value types

Strictly speaking, there’s no relation between Value Objects and .NET value types because the first is a design concept and the latter is a technical implementation detail.

However, there are a lot of similarity in these notions. Structs in .NET are inherently immutable because they are always passed by value. Also, they are much cheaper than reference types in terms of system resources. Look at DateTime struct from the BCL. It has a clear Value Object semantics: it is immutable and doesn’t have any identity fields.

In theory, you could use .NET value types as Value Objects. However, I wouldn’t recommend it. First of all, structs don’t support inheritance, so you will have to implement equality operators in every struct separately, which will lead to massive code duplication. Also, ORMs often don’t handle mapping to structs well. That said, I recommend you to always use classes for Value Objects.


Value Object is an important DDD concept. You should clearly show which of your domain classes is an Entity and which is a Value Object by inheriting them from Entity and ValueObject<> respectively.


  • Anders Baumann

    Hi Vladimir.

    Thanks for an interesting article!

    I have a question about how to store a value object. You write: “Value Objects should not have separate tables in database.” In theory I agree but in practice it turns out that it might be a place where it is necessary to make a compromise. As Jimmy Bogard writes: “Value objects are possible using Complex Types in EF and Composite objects in NH, but don’t use them. There’s all sorts of weird behavior around null values, and ultimately you’re going to run into friction that your domain model is at fundamental odds with your persistence model…. If you need a true Value Object, and it’s not just an encapsulated primitive, you’re much, much better off treating it as an entity in EF and managing the visibility/mutability/navigation yourselves.” (

    What do you think?


    • Vladimir Khorikov

      Hi Anders, great question!

      Complex Types in EF is indeed a mess, I tried to use them to introduce Value Objects and I too couldn’t make it work. At the same time, NHibernate doesn’t have such problems and handles them very well. I can’t remember any single issue with it (and I usually have a lot of value objects in my code bases).

      You should definitely take into account the restrictions the underlying framework imposes, I agree with Jimmy Bogard on that. So if you use Entity Framework as your primary ORM, the practice of not having separate tables for value objects should probably be avoided.

      As a side note: if you want to adhere to DDD practices, I recommend you to consider switching from EF to NH if possible. I know NH sounds more like a dinosaur these days and doesn’t get as much attention as EF from the .NET community, but the fact is: unlike Entity Framework, Hibernate was developed to help developers adhere to the best practices (DDD practices included) and NHibernate successfully inherited its traits. I worked with both of them for many years, and I can say that it’s too hard to fight EF if you want to create an isolated and clean domain model. It imposes too many restrictions and does too little to help maintain proper separation of concerns. NHibernate is still way ahead of EF here and I don’t see this state of affairs changing in any near future (considering the new version – EF7 – will be released soon).

      • Anders Baumann

        Hi Vladimir.
        Thanks for your answer. We use NHibernate at work and I wanted to try Entity framework in a hobby project. Mostly for the learning experience.

        I agree with you about the DDD aspect. However, EF also has some advantages: Code first migrations, async methods and better LINQ support:

        Not an easy choice. As always when it comes to tooling.


        • Vladimir Khorikov

          Yeah, EF has its own advantages. I personally think async methods is the only one that is notable comparing to NH. Regarding the code first migrations, I think Fluent Migrator is a good analogue this feature.

  • Luke

    Can you elaborate on your decision to not include the Comment property in the EqualsCore() and GetHashCodeCore() methods please? I’m very new to all this and don’t get why Comment isn’t included. Great blog by the way.

    • Vladimir Khorikov

      The decision of whether or not to include a field into the equality operations depends on the domain model. Here, I wanted to give an example of a situation where a field can be omitted: a comment in this case doesn’t contribute to the value object’s semantics, it’s just an arbitrary field set up by the user. Two addresses of the same Street and ZipCode should be considered the same even if the comments attached to them differ.

      I leave aside the question why the Comment field was introduced to the Address value object in the first place, I just couldn’t come up with a better example. Hope it conveys the overall idea, though. That is we shouldn’t automatically include all fields of a value object in its comparison operations at all times (although, that is what we will end up doing in most cases), we need to approach this task thoughtfully.

      • Luke

        Nice one Vladimir; that’s helped clear that up for me.

  • Peter Oostwoud-Sibiryak

    Hi Vladimir,

    Great article! I have a question about value objects not being persisted to the database.

    Are value objects only meant for (structural) validation? Does this mean they can never appear as a collection without being an entity?

    E.g. a customer has a collection of addresses. Addresses can/should have structural equality. When storing them it would require a separate table. Why not store them simply using the identity of the entity they belong to?

    Am I missing something?



    • Vladimir Khorikov

      Hi Peter,

      Having a collection of value objects indeed complicates this picture. They can appear in a collection but you need to either represent the whole collection as a value object (which is not the best way in many cases):
      or you need to nest a VO into an entity:

      Why not store them simply using the identity of the entity they belong to?

      Do you mean the identity of the customer? You won’t be able to introduce more than 1 address then (if you make the PK of Address == PK of Customer)

      • Peter Oostwoud-Sibiryak

        Hi Vladimir,

        Thank you for your response. I’ve read your articles on VO’s, interesting stuff. Doesn’t it all depend on the storage used for storing VO’s? When using a document store, the address collection could simply be stored as a nested collection. For relation databases (please note that I’m not a DBA :)) why not simply create a table with a non-unique clustered index? E.g.

        CREATE TABLE [test].[customer]
        ,[name] NVARCHAR(255) NOT NULL

        CREATE TABLE [test].[address]
        ,[street] NVARCHAR(255) NULL
        ,[housenumber] INT NULL
        ,[postalcode] NVARCHAR(255) NULL
        ,[residence] NVARCHAR(255) NULL

        CREATE CLUSTERED INDEX [IX_address_customerId]
        ON [test].[address]
        [customerId] ASC

        As addresses have no identity there seems no need to provide them with a primary key. Tim McCarthy has a similar approach on this on

        On the other hand, when a primary key is used, why automatically consider this as being the identity. Object models and database models can (should?) be different to be “optimal”. The PK can simply be considered a necessity for database reasons. The PK itself could simply be hidden in the implementation of repository for the object model.

        Curious how you think about this.



        • Vladimir Khorikov

          Doesn’t it all depend on the storage used for storing VO’s?

          It does.

          When using a document store, the address collection could simply be stored as a nested collection.

          That’s correct.

          On the other hand, when a primary key is used, why automatically consider this as being the identity.

          It’s true that we should aim at decoupling our domain model from the database but this has a limit. Potentially, you could make the domain model work on any type of database structure but an incompatible DB schema would fight you every step on this way. I’d recommend be pragmatic here and take into account the DB concerns while building the domain model (note that it doesn’t mean the domain model should be aware of those concerns, it still should be as isolated as possible).

          The PK is one example. You could completely abstract your model from the fact that the DB contains a PK but that would be a lot of unnecessary work. This will work fine in a document DB, but not in a relational one.

  • Sgolzari

    Hi Vladimir, I am new to DDD and ef. I am trying to implement value objects in my model. The value object I am dealing with right now consists of a series of bools which will become T/F columns against my entity. I am struggling to understand the point of the value object base class and why its methods are necessary. All of the resources I have read on the matter just say, here’s a base class for VOs without saying anything about why it is necessary.

    • Vladimir Khorikov

      The main benefit of the base class is being able to combine some of the equality logic into a single place, to avoid duplication. Another benefit is that when you see a class in code that inherits from ValueObject, it helps you understand the semantics of that class.

  • Manvel Ghazaryan

    Hi Vladimir, thank you for great article! I would love to see how you would implement Value Object that supports unit of measure. For example Distance might be in feet/inches/cm/meter/kilometers etc… How would you design Value Object that should consider units of measure (when creating, when comparing 2 distances with different units, when client of Value Object wants to get the value in specific unit ?)

    • Vladimir Khorikov

      That would be an interesting problem so solve. I think the implementation would depend on the number of such units of measure. If it’s finite and not too large, I would probably come up with a separate Value Object for each of them. That would give an additional protection from the compiler – it would point out places where I try to use one VO in place of another, e.g miles instead of kms. An alternative with two fields (Amount and UnitType) is good too, especially if the number of units is large. Create an enum with the list of all unit types and make sure you encapsulate all conversion and comparison inside the Value Object.

  • 3amprogrammer

    Hi Vladimir! I have a question about validation. As you probably know Value Objects protect our domain. They should be always valid. This is simple when we are dealing with Latitude or Longitude. The rules are simple, you can check them inside constructor. What would you do in the following cases:
    1. Pesel ( – in short it is and identity number everyone has in Poland. It’s validation is quite complex:

    Would you store this inside value object to preserve self-validation concept or follow the 2nd method described below?

    2. Email (just for the sake of example, imagine any other VO with a need of external validation) – we have a rule an email MUST be a real email. To check this, we use some service that pings this address and sees if it responds. How would you create such value object? What do you think about injecting validation service (domain interface, infrastructure implementation):

    Email.create("[email protected]", emailValidator)

    Of course this VO would be different in another context. If we already have the email in a database that means it’s valid and we don’t have to worry with this painful check. But the most important part of this question is injecting validator to create Value Object.

  • 3amprogrammer

    Hi Vladimir, I have a question about creating and validating Value Objects. I have 2 cases in mind:

    1. Validation is complex and we don’t use external library.
    Is implementing a validation inside VO itself a good idea or would you use patterns from second point? Here’s an example

    2. Validation is complex and we use external library:

    // private constructor, ensures valid phone
    Phone.create(„123-456-789”, phoneValidator);

    // PhoneFactory takes PhoneValidator upon construction,
    // but you can bypass this and create Phone yourself

    • Vladimir Khorikov

      I normally don’t an external validation library unless I need a functionality from that library that is hard to develop in-house.

      In #2.1, I don’t like the dependency on a validator, it violates the domain model isolation. Although, if the dependency is pure (doesn’t need calling out-of-process dependencies), it may be fine.

      #2.2 is not encapsulated. If you can bypass `PhoneFactory`, you can’t guarantee the domain model remains in a valid state at all times.

      • 3amprogrammer

        Thanks for the reply but with all due respect I still dont know the answer. How do you deal with complex validation? If not the solution with factory what are the alternatives?

        I can come up with many cases when this is a thing. For instance SSN number. Rules in different countries are different but the concept is the same. Another example is phone number. Would you put validation for 20 countries inside PhoneNumber value object? There is a huge dedicated library (from google btw.) for this. Implementing validation inside a VO covering all edge cases sounds like a nightmere. Yet I have to guarantree a PhoneNumber is correct, cause this is a critical concept in my domain.

        It all looks simple on paper, lets create a Latitude VO validate the argument range inside a constructor. This in fact is a really noble idea, but DDD is supposed to be used for complex domains and often times the validation of a value object is complex or tenant dependent (not like the examples from books).

        • Vladimir Khorikov

          Well, again, `Phone.create(„123-456-789”, phoneValidator)` may be fine (I assume phoneValidator is from the Google library) if this library is self-contained – doesn’t refer to out-of-process dependencies. After all, `int.TryParse()` is a library call too. The reason why I emphasize the lack of out-of-process dependencies is because domain model isolation is crucial for DDD. The goal is to preserve both encapsulation and isolation from out-of-process dependencies.

          • 3amprogrammer

            Thanks a ton!