21 Şubat 2023 Salı

Aggregates

  •  Aggregateler, Entity ve Value Objectlerin kümesidir.
  • Entity ve Value Objectlerin tek bir transaction içerisinde yönetilmesini sağlar. Dolayısıyla Entity ve Value Objectlerin tutarlılığından sorumludur. 
  • Aggregateler bir Id ye sahiptir ve aynı zamanda bir Entitydir.
  • Bir aggregate, başka bir aggregateyi navigation property olarak içermemelidir. Sadece Id sini içermelidir.
𝗛𝗼𝘄 𝘁𝗼 𝗗𝗲𝘁𝗲𝗿𝗺𝗶𝗻𝗲 𝗶𝗳 𝗮𝗻 𝗢𝗯𝗷𝗲𝗰𝘁 𝗦𝗵𝗼𝘂𝗹𝗱 𝗕𝗲 𝗧𝗿𝗲𝗮𝘁𝗲𝗱 𝗮𝘀 𝗮𝗻 𝗔𝗴𝗴𝗿𝗲𝗴𝗮𝘁𝗲 𝗥𝗼𝗼𝘁?🌟

In Domain-Driven Design, an Aggregate Root is a fundamental concept representing the entry point to an aggregate.

a cluster of related objects treated as a single unit for data management and consistency.

I often use a simple question to determine the Aggregate Root: 𝗦𝗵𝗼𝘂𝗹𝗱 𝗱𝗲𝗹𝗲𝘁𝗶𝗻𝗴 𝘁𝗵𝗲 𝗔𝗴𝗴𝗿𝗲𝗴𝗮𝘁𝗲 𝗥𝗼𝗼𝘁 𝗮𝗹𝘀𝗼 𝗿𝗲𝗾𝘂𝗶𝗿𝗲 𝗱𝗲𝗹𝗲𝘁𝗶𝗻𝗴 𝘁𝗵𝗲 𝗼𝗯𝗷𝗲𝗰𝘁𝘀 𝗶𝗻 𝘁𝗵𝗲 𝗮𝗴𝗴𝗿𝗲𝗴𝗮𝘁𝗲?

Consider an e-commerce system with entities like Order, OrderItem, and Customer. The Order serves as the Aggregate Root because deleting it should also delete OrderItems, which are meaningful only within the context of an Order. On the other hand, the Customer entity remains valid even after the deletion of the Order, indicating that it's not a good candidate to be inside the aggregate root.


İmplementasyon

  • Domain layera MediatR linki üzerindeki nuget paketi indirilir.

  • Doman > Primitives  altına  Entity.cs ,IDomainEvent.cs ve AggregateRoot.cs  isminde üç adet class oluşturulur.

  • Entity.cs
  public abstract class Entity : IEquatable<Entity>
    {
        protected  Entity(Guid id)
        {
            Id = id;
        }
        protected Entity()
        {

        }
        public Guid Id { get; private init; }

        public override bool Equals(object? obj)
        {
            if(obj is null)
            {
                return false;
            }

            if(obj.GetType() != GetType())
            {
                return false;
            }

            if(obj is not Entity entity)
            {
                return false;
            }
            return entity.Id == Id;
        }

        public bool Equals(Entity? other)
        {
            if (other is null)
            {
                return false;
            }

            if (other.GetType() != GetType())
            {
                return false;
            }

            return other.Id == Id;
        }
        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }

        public static bool operator ==(Entity? first, Entity? second)
        {
            return first is not null && second is not null && first.Equals(second); 
        }
        public static bool operator !=(Entity? first, Entity? second)
        {
            return !(first == second);
        }
    }
  • IDomainEven.cs
    public interface IDomainEvent : INotification
    {
    }
  • AggregateRoot.cs
    public abstract class AggregateRoot : Entity
    {
        private readonly List<IDomainEvent> _domainEvents = new();
        public AggregateRoot(Guid id) 
            : base (id)    
        {

        }
        protected AggregateRoot() { }

        public IReadOnlyCollection<IDomainEvent> GetDomainEvents() => _domainEvents.ToList();
        public void ClearDomainEvents() => _domainEvents.Clear();
        protected void RaiseDomainEvent(IDomainEvent domainEvent)
        {
            _domainEvents.Add(domainEvent);
        }
    }

Hiç yorum yok:

Yorum Gönder