To enable consistent comparisons of domain objects, alter StaffMember to inherit from Entity, and add a DomainSignature attribute above the property(s) which makes the staff member unique, as follows:
using SharpArch.Core.DomainModel;
...
public class StaffMember : Entity
{
...
[DomainSignature]
public string EmployeeNumber { get; protected set; }
...
}
Inheriting from Entity and adding the attribute has had a few effects on the StaffMember object. Equals() and GetHashCode() have been provided by default for consistent behavior. Contrast to the original inspiration from http://devlicio.us/blogs/billy_mccafferty/archive/2007/04/25/using-equals-gethashcode-effectively.aspx, Equals and GetHashCode now work independently of each other; consequently, in theory, two objects can have the same hashcode without being equal. This is very much by design. Additional differences between the current architecture and what was described in the blog post include: GetHashCode() has been moved up to Entity so only the “domain signature” has to be defined via the inclusion of attributes. Furthermore, as shown in the example above, the comparison behavior has been abstracted into a Entity class so as to serve as an optional base class for non-persistent objects. To read more about the importance of providing Equals and GetHashCode for NHibernate, see http://www.hibernate.org/hib_docs/nhibernate/html/persistent-classes.html#persistent-classes-equalshashcode.
For calculating the HashCode, the “domain signature” gets automatically created by performing bitwise XORs, and some other fancy math, with all the domain signature properties resulting in an int HashCode defining what makes an object unique. For checking objects for equality, each domain signature property is compared, one by one. Alternatively, you can forego using attributes and define the domain signature comparison functionality yourself by overriding HasSameObjectSignatureAs(BaseObject compareTo) . Take a look at Northwind.Core/Order for an example of doing so.
To reiterate the easier alternative, you could simply add the DomainSignature attribute above both the respective properties which has the same behavior as the example. To learn more about the difference between an entity and a value object, as well as a more in depth analysis of what defines an entity’s domain signature, I highly recommend reading Domain Driven Design by Eric Evans.
So what if the domain signature happens to include a complex reference type (a non-primitive) as part of its domain signature? For example, assume that a “HomeAddress” object is part of what makes a StaffMember unique. The property comparison will invoke Equals between the properties, so it’s important to have the composite objects implement Equals as well, either by inheriting from Entity, ValueObject (which uses all of the object’s properties for comparison) or providing your own Equals method.
The following is an illustrative example - i.e., don’t modify the tutorial code you’re working on to reflect this – that shows creating a multi-part signature using the DomainSignature across multiple properties. It’s alright if the properties which make up an object’s domain signature are value or reference types; the base class will take nulls into consideration when comparing the objects.
using SharpArch.Core;
using SharpArch.Core.PersistenceSupport;
using System;
namespace Northwind.Core
{
public class StaffMember
{
...
[DomainSignature]
public string FirstName { get; set; }
[DomainSignature]
public string LastName { get; set; }
[DomainSignature]
public Address HomeAddress { get; set; }
}
}