Home » C# » How to work with Value Object In C#

How to work with Value Object In C#

Implementing value objects in your project is something that every software has to do. It may sounds like a simple task but from my experience I can tell you that it is less easier than it looks like. In fact, it is easy but developer does not really understand the difference between an enum, a entity or a value object.

A value object is a class that has information that does not have a unique identifier for every usage but a unique identifier for the instance itself. A value object are reused across your application many times which remove a lot of complexity that you would have by having a unique identity for each of these instance. For example, if you have a Person class that has a relationship status. This is the perfect example for value object. You create a class for every of your status like one for “Married” and one for “Single”. You could have a Married entry for each person but that would result to a lot of duplicate. You could have used a C# enum or a C# constant but this would result to a weak integrity between your classes and also in your persistence storage. The integrity is weak in the code because you would pass between methods string or enum which could be casted from integer. The string could be anything and would require a lot of validations. In the database, you save in a column a string or an integer (for the enum). In both case, you do not have any validation. This is where value object can shine. You can have a strong integrity in code but also in the database. You can also have a big performance saving by having the same object reused across the application. For example, if you have 1 million Person that are single, 1 million will be linked to the same object. You do not have redundancy.

Before going any deeper, let’s examine a second example that is from Eric Evans in his book Domain Driven Design. Imagine, a box of markers with different colors. Each marker will have a value object that define the color. Each color does not have a different id for each marker, neither have a different id for each lines drawn. You would have simply the class Marker having a reference to the value object that define the color. You also have for each Line class a reference to the value object color to know the color of the line. In both case, it would be too big in resource to save a new entity for each Markers and Lines.

Another example could be with a simple state that change between Active, Inactive, NotSet. Those three states can use value object to define the state of any entity that require to have a state defined. Or another example could be that you have several currencies that you want to handle in your program. Every amount is set to a currency. The list is well defined and do not change dynamically so you can create a class by currency. This is crucial to have your value object not dynamic. It is the cost of this pattern. You cannot have something dynamic because you need to have the value object defined in code, in a class.

CurrencyTypeValueObjectExample

The image above shows that we have a value object named “CurrencyType”. This mean that if you have a class that has a CurrencyType property.

public void Money
{
    public CurrencyType Currency { get; set; }
    public decimal Amount { get; set; }
}

This usage is very strong because you can only assign a CurrencyType. It would be weak to have used a string for the currency like the code below.

public void Money
{
    public string CurrencyType { get; set; }
    public decimal Amount { get; set; }
}

The problem is the same for an integer is assigned. The Money class could have used an enum but at the time of saving everything, the table would have the decimal value for the amount and an integer for the currency type. The problem is now at the database level where the integer could been altered and when loaded back in the software would cause instability. However, the value object could not be unstabilized because of the database integrity. Since every value object are reflected by a table with entries, those entries are referenced by a foreign key to the one that use the value object.

For example, if you have an Item that has a price of type Money, you could set the CurrencyType to USD. In the database, the table Item would have a column price and a column currency type. The currency type would have a foreign key to the table currency type.

Every values of the value object is a class. For example, if you have a Canadian currency and an American currency you need two classes.

public class CanadianCurrency:CurrencyType
{
	public CanadianCurrency()
	{
		base.Id = 1;
		base.Name = "$CDN";
		base.Culture = new CultureInfo("fr-CA");
	}
}

public class USACurrency:CurrencyType
{
	public USACurrency()
	{
		base.Id = 2;
		base.Name = "$USD";
		base.Culture = new CultureInfo("en-US");
	}
}

You can have anything you want in the value object. The minimum is to have a identifier that will be the primary key in the database. In the example above, it is an integer but could be a string. The important thing is to have all your implementation to inherit the same class. In that case, it is CurrencyType.

public abstract class CurrencyType : ValueObject<CurrencyType>
{
	public static readonly CurrencyType Canada = new CanadianCurrency();
	public static readonly CurrencyType UnitedStatesOfAmerica = new USACurrency();
}

The two static property act as a factory and are not required. It is just easy to select values because instead of instantiate yourself the entity your use the factory which offer all possibles choice with Microsoft Intellisense.

//Instead of :
item.CurrencyType = new CanadianCurrency();
//Use :
item.CurrencyType = CurrencyType.Canada;

You do not have to inherit to ValueObject like in the example above, but if you do, it will give you some additional possibility like having automatic parsing from primary value (integer in our example but could have been string) to the value object. Imagine a scenario where you let the user choose from a combox box the value object. The value is returned as the unique identifier. In the case of the money currency, the value 2 could be returned to the controller and you have from this value get back the value object into the model object. This can be done by a method that map the id to the value object.

public abstract class ValueObject : IEntity
{
	public int Id { get; set; }
	public string Name { get; set; }

	public override bool Equals(object obj)
	{
		if (ReferenceEquals(null, obj))
		{
			return false;
		}
		if (ReferenceEquals(this, obj))
		{
			return true;
		}
		if (obj.GetType() != this.GetType())
		{
			return false;
		}
		return Equals((ValueObject) obj);
	}
	protected bool Equals(ValueObject other)
	{
		return Id == other.Id;
	}

	public override int GetHashCode()
	{
		return Id;
	}

	public static bool operator ==(ValueObject left, ValueObject right)
	{
		return Equals(left, right);
	}

	public static bool operator !=(ValueObject left, ValueObject right)
	{
		return !Equals(left, right);
	}
}

public abstract class ValueObject<TValueObject> : ValueObject where TValueObject : IEntity
{
	public static TValueObject GetFromId(int value)
	{
		Type type = typeof(TValueObject);

		var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
		foreach (var field in fields)
		{
			var fieldValue = (TValueObject) field.GetValue(null);
			
			if (fieldValue.Id == value)
			{
				return fieldValue;
			}
			
		}
		throw new KeyNotFoundException(string.Concat(value, "cannot be found in any static fields."));
	}
}

It may look like a lot of code but it is not. The first class that is not generic only override some operator to simplify the comparison between value object of the same type. The generic version give the possibility to get from the the id the value object. It uses reflection to get for each implementation of the value object type if one has the Id passed by parameter.

item.CurrencyType = CurrencyType.GetFromId(viewModel.CurrencyIdFromWebForm);

This pattern works very well with Entity Framework.

public class CurrencyTypeConfiguration : ValueObjectConfiguration<CurrencyType>
{
        public CurrencyTypeConfiguration()
        {
        }
}

The configuration is very similar to every of your value object. The trick is all in the inherited class, ValueObjectConfiguration that take the type in its generic parameter.

public abstract class ValueObjectConfiguration<T> : EntityTypeConfiguration<T> where T : ValueObject
{
    protected ValueObjectConfiguration()
    {
        Map(a => a.MapInheritedProperties());
        HasKey(p => p.Id);
        ToTable(typeof(T).Name, Constants.SchemaNames.ValueObject);
    }
}

The configuration set the inheritance to MapInheritedProperties. This create a single table with all classes. This mean that all value of your value object are in a single table named by the name of the generic class name. In our example, the table created by Entity Framework is named CurrencyType and has two entries. One with ID 1 and one with ID 2.

ValueObjectTableExample

As you can see in the code and also in the screen shot of the table, a primary key is created. This ensure that you have a unique value object identifier but also that if you use the value object into another entity that this one is strongly referenced.

One more thing. This is very efficient in term of performance. If you have your Item, you do not need to load from the database the currency information. First, because you can have the Id directly from the entity that use the value object. This is because the foreign key is already in the table that use the value object. You only need to load if you have created a lot of data that is not stored in the class but since it is a value object all this information is already in the class. Second, because you can load the whole value object from the method we have defined in the ValueObject class. A trick is to never include/load the value object but to use the method to get back the whole object.

public class Item
{
   public int CurrencyTypeId
   {
       get { return this.Currency.Id; }
       set { this.Currency = CurrencyType.GetFromId(value); }
   }

   /// <summary>
   /// This is ignored by EntityFramework
   /// </summary>
   public CurrencyType Currency { get; set; }
}

The code above show a way to do it. You can tell Entity Framework to ignore property and use the CurrentyTypeId. This way, it load and save only the unique identifier and allows you to use the value object property in your business logic. As you can see, the setter of the currency type set the value object value from the GetFromId. The getter also does not link to a integer but to the currency value object. This guarantee us to use the simplest way to save value to entity (by having the foreign key in the class) and to have integrity in the value because it pass through GetFromId() method that thrown an exception if the value is not valid.

The last example is good in the scenario where you have an Entity Framework Complex Object. Complex Object cannot have a navigability association. But, if you have a normal entity, than the best is to have the foreign key in the database. If we also want to have the performance, this mean that we do not want to load the value object object with an Include (to avoid join). To be able to have performance and integrity the best is to have the entity use scalar property that hold the foreign key.

Full Working Version of Value Object

We have discuss about few way to implements value object. Let’s warp up everything in a small console application. This final version works for every situation. This mean that it works with required attribute, work by setting the property to null and having a scalar property to the value object, it also work without having to use Include statement to reduce the amount of join and finally, it can use Entity Framework when saving to avoid adding the value object but just referring to it.

First of all, let’s define our context. The context define the connection string and remove everything in the configuration about lazy loading, detection and proxy. It also setup 2 entities. The first one is Parent and the second one is Child. A Child will have a reference to a Parent. The Child is referencing a Parent which simulate the “value object”.

    public class MyContext : DbContext
    {
        public MyContext() : base("MyContextConnectionString")
        {
            base.Configuration.LazyLoadingEnabled = false;
            base.Configuration.AutoDetectChangesEnabled = false;
            base.Configuration.ProxyCreationEnabled = false;
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Parent>();
            modelBuilder.Entity<Child>();
        }
    }

The Parent, simulating the value object, has a unique identifier, ID, and a name. It also has the “Create” method which is, in fact, the method that we would use to get the value object. It is the method that we have previously named “GetFromId”. This time, we make it very simple for the purpose of the example.

public class Parent
{
    public int Id { get; set; }
    public string NameParent { get; set; }

    public static Parent Create(int id)
    {
       return new Parent { Id = id };
    }
}

The Child class, the one that has the value object, the Parent in this example, is more complex. First of all, we do not use auto-property. This time, we are using properties and fields. One for the class and one for the scalar that represent the foreign key. We do want that to not have to include (create a SQL Join) everytime. TheOnlyParent property return the field directly. That mean that if the field is Null that we will have Null as value. This is what we want for Entity Framework to only save back the Id and not to verify if it has a match with the property. The Child class also has the scalar property that return the field but as something special in the setter to create the object from the method of the value object that can create the value object by its ID.

    public class Child
    {
        private Parent theOnlyParent;
        private int theOnlyParentId;
        public int Id { get; set; }
        public string NameChild { get; set; }
        [Required]
        public Parent TheOnlyParent
        {
            get
            {
                return theOnlyParent;
            }
            set
            {
                theOnlyParent = value;
                if (value != null)
                    TheOnlyParentId = value.Id;
            }
        }

        public int TheOnlyParentId  
        {
            get { return theOnlyParentId; }
            set { 
                theOnlyParentId = value;
                theOnlyParent = Parent.Create(value);
            }
        }
    }

To be very bulletproof with Entity and this scenario of having a reference to an existing object, let’s add a Required attribute into the property field. This mean that Entity will verify if this property is set. That is also mean that setting to Null will raise a validation exception. This is why, every value object (or any entity that link an existing entity) must be set to unchanged.

 static void Main(string[] args)
        {
            Console.WriteLine("Start create database");
            Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());
            Console.WriteLine("Start adding Parent");
            var p1 = new Parent {NameParent = "Test Parent Name#1"};
            int parentCreatedId;
            Console.WriteLine("Context");
            using (var context = new MyContext())
            {
                context.Set<Parent>().Add(p1);
                context.SaveChanges();
                parentCreatedId = p1.Id;
            }
            Console.WriteLine("Start adding a child from a different context");
            var c1 = new Child { NameChild= "Child #1" };
            c1.TheOnlyParentId = parentCreatedId;
            c1.TheOnlyParent = new Parent {Id = parentCreatedId};
        
            Console.WriteLine("Context");
            using (var context = new MyContext())
            {
                Console.WriteLine("*Change State Child");
                context.Entry(c1).State = EntityState.Added;
                Console.WriteLine("*Change State Child->Parent Navigability Property");
                context.Entry(c1.TheOnlyParent).State = EntityState.Unchanged; // We do not want to create but reuse
                Console.WriteLine("*Save Changes");
                context.SaveChanges();
            }
            Console.WriteLine("End");
            Console.ReadLine();
        }

This code runs without a problem. The property can be set OR can be null and in both case, the association is created in the database. This code as a strong integrity by having the foreign key created but also is aim for performance with the possibility to load the entity (for example Child) without having to include the associate entity (the Parent).

Finally, value object is a simple pattern that should not be a nightmare to implement in your project. If well designed, it can be very easy to use. Entity Framework works very well with value object and performance are as fast as any other solution.

If you like my article, think to buy my annual book, professionally edited by a proofreader. directly from me or on Amazon. I also wrote a TypeScript book called Holistic TypeScript

15 Responses so far.

  1. Robison Karls Custódio says:

    Hey man, thanks for the explanation, I was confused about the whole concept of value Object, I mean i knew what it was, but not sure how to handle it in code.

    Thx.

  2. I was under the impression that ‘ValueType’s were not supposed to have Ids. What make a value type unique is the values it holds NOT and ID.

    Entities do have IDs and this is what makes them unique. I am basing my understanding on DDD princliples.

    • They have an id per “type” not per “instance”. For example, you have Pen with ValueType for Color. All Red pend will refer to the same ColorValueType.Red. You need an ID to be able to persist the Value. Let’s say that you have Pen#100 which is red. You need to persist in your database that the Pen#100 is red, the column will be ColorValueType #1. You create a new Pen, #101. This one is also red. It will also have the ColorValueType id #1. Is that clearer?

      • Thank you for your reply, and yes that does help thank you.

        We have just “flattened out” the value types into the DB row, so for a Pen with two properties “ColourName” and “RGBAColour” you would have to have two columns in the row matching the two properties.

        When you say “You need an ID to be able to persist the Value” does that mean you are allowing your ORM to define the structure of your ValueTypes. surely in DDD the domain is king and should be ignorant of the access layer or it’s requirements. Say you moved to a NoSql backing store you might not need that “Type ID” but now it is already baked into your ValueType, so you would kind of have to leave it there. Or am I still missing your point?

        • Hello,

          There is two way to do it. You can persist it by having 1 table that is holding all values for the value object or just having the unique identifier (id). With Entity Framework, I just have all values in the database, it makes the table easy to read + have a strong integrity. Also, to be noted that the Value object is most of the time just ID + Name, so pretty simple.

          For example, the Currency value object which can be USD and CAD. The table is :

          Table Name: CurrencyValueObject
          Column 1 : ID
          Column 2: Name
          

          In fact, in the post you can see a screenshot of it. When used in C#, the code is just using the object which has a override on the Equal so it’s used only like this:

          if (myEntity.CurrencyType == CurrencyValueObject.USD)
          

          For NoSql, or Caching, it works too, you just have that ID arrow. Even in a NoSql you need to have unique identifier to retrieve information. Without ID, it would be the “name of the currency”, like USD that would refer the USD object which could have the full name “United States Currrency” or any other possible constant values. At the end, you need something to represent the value object. For example, in my post I would have the color “Red” to use identifier 1. If you want to not use ID, you could always use the string “Red” to identify the value object.

          • Duane Wingett says:

            Hi, Thank you for a quick response.

            Ok, putting the ID issue aside for a moment I can see what you are saying and I think your solution is a very good replacement for C# enums – which I’m sure you’d agree – are always troublesome.

            In my mind though, ValueObjects should be persisted WITH the entity in-line in the row, in the same was as you would persist a `string` or an `int`, as it is stored as a matter of FACT. For example say you have a Person entity with a “Name” property – for record #1 “Name” might be “Bill”. For record #2 “Name” might be “Ben”. When record #3 comes along and needs “Name” to also be “Bill” you don’t spin up another table with all the available “Names” in it like:
            `
            Id | Name
            1 | Bill
            2 | Ben
            3 | Fred
            `

            and then reference the name field with NameId pointing to the Id of 1 for the two “Bills” and 2 for the “Ben”. You would store the actual value in the column for “Name”, surely?

  3. J Adjare says:

    Hi Patrick,

    Interesting post, similar to the previous commenter, I’m not convinced a ValueObject should have an Id by design. I appreicate that ValueObjects sometimes need Id’s by necessity, for example when overcoming limitations of persistence layers.

    In your response to Duane you talked about a type of colour that’s red and two different pen entities that both have red ink. In the way you describe the answer it sounds more like a FlyWeight pattern, in that you have a pool of different coloured ink pots, when a pen uses a colour its assigned an identifier for that colour, rather than the colour itself. This way the pen can go back to the same pot of ink for each pen stroke.

    If I was to think about it in the physical world, then what’s happening is that the each pen is being dipped into a pot of ink so it can use the ink to draw a stroke. In this scenario, each pen and each pot of ink is in itself an entity. If the pot of ink ages and changes colour so will each pen’s stroke change colour when it’s dipped in to the ink. If instead we stored the ink in the pen, then each pen would exist as its own entity complete with it’s own ink. We can take the pot of ink away and still have pens full of ink. If the hue of one of the pen’s ink changes over time it will not necessarily mean that any other pen’s ink will change. The latter I believe is the essence of a value object.

    This stack overflow question talks about dealing with value objects and how it’s common to denormalise a value object into it’s parent entity’s database row.
    http://stackoverflow.com/questions/30408498/how-to-deal-with-value-objects-in-entity-framework

    • Hello,

      At the end, the important thing is that every Pen is using the same object for its Red instead of having one instance of Red. The “value” is of “Red” object. Having an ID allows you to have a strongly reference in the database and allow you to query by all entities that have a Color of 1 (Red). If you avoid using ID, than you will need to store the name of the Value Object in your database. Do you believe it’s better that way?

  4. J Adjare says:

    @Patrick

    “If you avoid using ID, then you will need to store the name of the Value Object in your database. Do you believe it’s better that way?”

    I think it depends on what problem you’re solving. If I was to avoid storing the Id of the Value Object, I wouldn’t store its name in the database, instead I would store the value of each component property that makes up the Value Object, e.g. in this example the Red, Green, Blue and Alpha values that are used to define a colour.

    The example you present is a good and efficient design, but I’m personally not sure it’s truly in the spirit of a Value Object. My understanding is that Value Object’s don’t have Identifiers (except to overcome issues with ORM tools). This is the definition of a Value Object from the DDCommunity.org site (http://dddcommunity.org/resources/ddd_terms/)
    “[[Value Object]] An object that describes some characteristic or attribute but carries no concept of identity.”

    Colour itself is quite a good example of a Value Object in .NET. Here we’re provided an Color object (implemented as a Struct) which represents the component values required to make a colour. We’re also provided some handy predefined colours, e.g. Color.Red. If we assign a Pen.Color ( public System.Drawing.Color Color {get; set;} ) property the value of Color.Red it is not given a pointer to the colour but simply takes a copy of the R,G,B and Alpha values.

    It’s possible that I’ve missed the point of how Value Object’s can be implemented, perhaps both ways are valid. What do you think?

    • Hello,

      There is no hard rule about what is wrong or good. If you need to store your object and what color it has (System.Drawing.Color) in the database you will need to use a unique identifier which will probably be the name of the value object. In term of performance, a string is less optimized than an id. If you do not need to store that information, just don’t use the id. Both case are valid.

      • I’m still not convinced that a ValueObject should eve have an ID. According Jimmy Bogard in a DDD world value objects do not have an ID. Their uniqueness is driven by the uniqueness of their property values, not an ID field. I strongly believe that if you are letting your ORM dictate that your ValueObjects have an ID then I think you are missing the point slightly.

        Quote:
        Value Object Requirements
        In the Domain Driven Design space, a Value Object:
        – Has no concept of an identity
        — Two different instances of a Value Object with the same values are considered equal
        -Describes a characteristic of another thing
        -Is immutable

        Ref:
        https://lostechies.com/jimmybogard/2007/06/25/generic-value-object-equality/

        • Hello Duane,

          What I am describe does have an uniqueness by their value. You won’t see two “Red” color. All instance are the same in C# too, they are immutable. Can you tell me how will you save those ValueObject reference to the database to have a strong reference integrity? What Jimmy Bogard describes is all fine, but doesn’t answer that question. What I am doing here is pushing the value object up to the database, and still only have a single, unique, immutable entry for each type. For example, I’ll have 10 defined colors in C#, all instance are unique and immutable BUT I also have 1 entry for each of them in the database, hence having a strong reference to them in the database.

          If that doesn’t fit in your philosophy, I am fine with that. However, I would be very interested to see how do you save those ValueObject to you entities in the database.

          • Hi Patrick,

            I would not store the value objects in the database in their own tables. ValueObjects should not be overly large in the data they hold, just rich with business logic. Therefore for a colour object with the following properties “Name” and “RGBA”, which a “Pen” object might use, the Pen table would have two columns “ColourName” and “ColourRgba” in it’s row. These would hold values that were a FACT at the time of writing them.

            I don’t think there should be shared objects in the database for the colour values. After all take me. I have a Firstname of “Duane” and a Surname of “Wingett”. Now there is another “Duane Wingett” in the USA, so if we both had an account in Amazon, and they used a relational database for storing account information I would not expect them to have a table with a row with an arbitrary “Id” and “Firstname” of “Duane” and a “Surname” of “Wingett” which both our records would refer to by the “Id”… Would you?

          • I think you want to be more theoric than practical here.

            I am illustrating here a way to do Value Object that automatically generate the table for you to have that strong reference from your entities to the Value Object. If you do not like it and think it’s wrong because of a Jimmy, than do what Jimmy says. If you need to have something autogenerated because your requirement is to have a database that has only a set of values allowed with validation to always be in a correct state than do like I say. That’s it Duane, no need to go deeper.

          • Duane Wingett says:

            @Patrick, You don’t need to save them in the database in their own table, they are saved AS PART of the parent entity. The individual values of the ValueObject are saved in the row of the ENTITY it it serves.

            Anyway, I guess we are just going round in circles both covering the same ground, so we will just have to agree to disagree on the approach used for persisting ValueObjects.

            Eitherway, it’s been a great discussion.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.