One important thing to consider when implementing a domain-driven design is object identity.
In most languages, each object identity is determined by the memory address of the object, but if we are implementing a DDD then we shoud redefine object identity in terms of our domain. For example, let’s suppose we are working in a bank domain, and we have an Accout class, then you should define the identity of Account objects based on the account number.
When working with C#, there are four methods related to the identity of objects, all of them defined in the root class Object:
public virtual bool Equals(object obj);
public static bool Equals(object objA, object objB);
public virtual int GetHashCode();
public static bool ReferenceEquals(object objA, object objB);
Let’s analyze them one by one.
bool Equals(object obj)
By default this method will compare object’s memory address, but that is not correct when implementing a DDD. As mentioned before identity of our domain classes should be define in tern of domain concepts, so we should override this method. Continuing with the Account class example, this method should compare account number: same account number then same object.
public override bool Equals(object obj)
{
Account otherAccount = obj as Account;
if (otherAccount == null)
return false;
return this.Number.Equals(otherAccount.Number);
}
static bool Equals(object objA, object objB)
This method is static and just invokes Equals method of instance objA passing to it the objB as a parameter.
int GetHashCode()
This method is not directly related to object’s identity. It is used when a hash code is needed to represent the object, for example if we want to store the object in a hash-based struture like a hashtable. From msdn: » The default implementation of the GetHashCode method does not guarantee unique return values for different objects. Furthermore, the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value it returns will be the same between different versions of the .NET Framework. Consequently, the default implementation of this method must not be used as a unique object identifier for hashing purposes.»
When implementing a DDD we should override this method in our domain classes to return different values for not equal objects. In the Account class example we could use the account number as the hash code.
public override int GetHashCode()
{
return this.Number;
}
static bool ReferenceEquals(object objA, object objB)
This method simply compares memory addresses, the same behaivour that Equals default implementation.
Well, this is it, I hope this post to clear enough.
If you want to see some tests running to validate this and make your own test you can download my code from here.
In future posts I will write about the relation of this with the equals operator (==) and the importance of equals method when working with persistence frameworks like NHibernate.