In Domain Driven Design, one of the defining characteristic of an Entity is that it has an identity.
Problem:
I am not able to provide a unique identity to Entities on instance creation. This identity is only provided by the repository once the entity is persisted (this value is provided from the underlying database).
I cannot begin to use Guid
values at this point. The existing data is stored with int
primary key values and I cannot generate a unique int on instantiation.
My solution:
- Each Entity has an identity value
- The identity is only set to a real identity once persisted (provided by the database)
- The identity is set to default when instantiated before persistence
- If the identity is default, entities are comparable through reference
- If the identity is not default, entities are comparable through identity values
Code (the abstract base class for all entities):
public abstract class Entity<IdType>
{
private readonly IdType uniqueId;
public IdType Id
{
get
{
return uniqueId;
}
}
public Entity()
{
uniqueId = default(IdType);
}
public Entity(IdType id)
{
if (object.Equals(id, default(IdType)))
{
throw new ArgumentException("The Id of a Domain Model cannot be the default value");
}
uniqueId = id;
}
public override bool Equals(object obj)
{
if (uniqueId.Equals(default(IdType)))
{
var entity = obj as Entity<IdType>;
if (entity != null)
{
return uniqueId.Equals(entity.Id);
}
}
return base.Equals(obj);
}
public override int GetHashCode()
{
return uniqueId.GetHashCode();
}
}
Question:
- Would you consider this to be a good alternative to generating Guid values on instance creation?
- Are there better solutions out there for this problem?
uniqueId
field after inserting? And how does your repo access that field when updating, to know which row to update? – Uptown