1

I want to apply/practice DDD with my new project hence I am creating those typical DDD base classes, i.e., Entity, ValueObject, AggregateRoot and so on.

Question: When you have the Entity base object implement IEquatable, should two entities with default value of the identity (Id) be considered as Not equal or equal?

For example, I use Guid type for the identity

public interface IEntity
{
    Guid LocalId { get; }
}

public abstract class Entity : IEntity, IEquatable<Entity>
{
    public Guid LocalId { get; private set; }

    protected Entity()
    {
        this.LocalId = Guid.Empty;
    }

    protected Entity(Guid id)
    {
        if (Guid.Empty == id)
        {
            id = Guid.NewGuid();
        }

        this.LocalId = id;
    }

    public bool Equals(Entity other)
    {
        if (ReferenceEquals(other, null))
        {
            return false;
        }
        if (ReferenceEquals(other, this))
        {
            return true;
        }

        // **Question** - should I return false or true here?
        if (other.LocalId == Guid.Empty && this.LocalId == Guid.Empty)
        {
            return false;
        }

        return (other.LocalId == this.LocalId);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(obj, null))
        {
            return false;
        }
        if (ReferenceEquals(obj, this))
        {
            return true;
        }
        if (!obj.GetType().Equals(typeof(Entity)))
        {
            return false;
        }

        return Equals((Entity)obj);
    }

    public override int GetHashCode()
    {
        return this.LocalId.GetHashCode();
    }

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

    public static bool operator!=(Entity left, Entity right)
    {
        return !Equals(left, right);
    }
}
David Liang
  • 20,385
  • 6
  • 44
  • 70
  • Just a question not related to your question: is it a c# thing to define this base clases? In `PHP`, I like to a avoid inheritance, especially in domain objects (entities, aggregate roots, value objects). – Constantin Galbenu May 26 '17 at 18:45
  • @Constantin: no, it isn't a C# thing :) --- it is a design choice made by some folks. I don't use these myself and wouldn't recommend it either. Does't hurt but also doesn't really add much value IMHO. – Eben Roux May 26 '17 at 19:27
  • @David, to answer your question: technically the "objects" are the same but from a business point-of-view having an entity/aggregate without a key makes little sense and the equality, or lack thereof, has no meaning. – Eben Roux May 26 '17 at 19:28
  • Good. I'm glad :) – Constantin Galbenu May 26 '17 at 19:29
  • @ConstantinGALBENU: It's true that creating a base class for, for example, Entity is just a matter of your design and programming style. I did that because I am seeing all my entities would have the same type of identity, GUID. Some forks like to have a generic Entity base class so that you can pass different types for the identity. – David Liang May 26 '17 at 21:30
  • @EbenRoux: So in other words, you would like / prefer to return false and say "Nope, two entities that have no ids are not equal"? – David Liang May 26 '17 at 21:34
  • 1
    @David: I'd probably go with an exception. Would there really be any sense in comparing invalid entities. There is quite a fine line between what is a technical requirement vs what is truly specific to the domain being modeled. Is your domain expert concerned about this aspect? I doubt it :) – Eben Roux May 27 '17 at 05:32

1 Answers1

0

If you want to follow the book on this then remember that:

An object that is not defined by its attributes, but rather by a thread of continuity and its identity.

Now, in this context identity means "the property of objects that distinguishes them from other objects", which in most cases means the entity primary key (if your entities are persisted in a database) or some kind of Id attribute, in most cases a GUID will do the trick.

So to answer your question:

  1. Yes, they're the same entity.
  2. Be careful with how you create your Id's
yorodm
  • 4,359
  • 24
  • 32