using MediatR; namespace Common.Domain.Abstractions; public abstract class Entity { private int? _requestedHashCode; public virtual Guid Id { get; protected set; } private List _domainEvents = []; public IReadOnlyCollection DomainEvents => _domainEvents.AsReadOnly(); public void AddDomainEvent(INotification eventItem) => _domainEvents.Add(eventItem); public void RemoveDomainEvent(INotification eventItem) => _domainEvents.Remove(eventItem); public void ClearDomainEvents() => _domainEvents.Clear(); public bool IsTransient() => Id == default; public override bool Equals(object? obj) { if (obj == null || !(obj is Entity)) return false; if (ReferenceEquals(this, obj)) return true; if (GetType() != obj.GetType()) return false; Entity item = (Entity)obj; if (item.IsTransient() || IsTransient()) return false; else return item.Id == Id; } public override int GetHashCode() { if (!IsTransient()) { if (!_requestedHashCode.HasValue) _requestedHashCode = Id.GetHashCode() ^ 31; // XOR for random distribution (http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx) return _requestedHashCode.Value; } else return base.GetHashCode(); } public static bool operator ==(Entity left, Entity right) => Equals(left, null) ? Equals(right, null) : left.Equals(right); public static bool operator !=(Entity left, Entity right) { return !(left == right); } }