相关实体的DDD Dispatch事件

问题描述 投票:1回答:1

要禁用与我们通常关联的用户配置文件

  • 从db加载用户
  • 调用User.RemoveProfile(ProfileId)方法。
  • 在这个方法中,我们将在列表中找到指定的配置文件,然后我们调用Profile.Disable()方法
  • Profile.Disable()内,我们举起了ProfileDisabled事件。
  • 我们完善了与用户+相关的实体(在这种情况下是配置文件)到DB。

目前,事件存储在每个实体内。当我们在数据库中持久保存用户时,我们会查看用户下的事件,而不是所有关联的配置文件。因此,我们不会发送个人资料事件而会丢失。

供您参考,这是我们用于调度事件的代码:

public abstract class Repository
{
    private readonly IMediator _mediator;

    protected Repository(IMediator mediator) => _mediator = mediator;

    // Future: Use EventStore for audit
    /* Bug: Disable profile raises an event stored at the profile level. When user gets updated only
       user events are dispatched. Profile events are lost... */
    protected async Task DispatchEventsAsync(Entity entity, CancellationToken token)
    {
        Ensure.Any.IsNotNull(entity, nameof(entity));
        await Task.WhenAll(entity.Events.Select(e => _mediator.Publish(e, token)));
        entity.SuppressEvents();
    }
}

Entity在哪里:

public interface IEntity { }

public abstract class Entity : IEntity
{
    private readonly List<DomainEvent> _events = new List<DomainEvent>();

    [NotMapped]
    public IReadOnlyList<DomainEvent> Events => _events.AsReadOnly();
    public bool HasEvents => _events.Any();

    protected void Emit(DomainEvent eventItem)
    {
        if (eventItem != null && !_events.Contains(eventItem))
            _events.Add(eventItem);
    }

    public void SuppressEvents() => _events.Clear();
}

正如您所看到的,Entity不了解相关实体。这无法访问相关事件。

怎么处理这个案子?这是否意味着只有Aggregate Root可以引发事件?

Thx Seb

.net .net-core event-handling domain-driven-design repository-pattern
1个回答
0
投票

我猜你有两个实体的聚合:用户和个人资料。而用户就是AR。

在聚合上执行操作时会引发事件,因此您应该将它们与AR一起存储。

在您的情况下,操作是“user.removeProfile(profileId)”,因此AR应该引发事件“ProfileRemovedFromUser”或类似的事情。

注意:您的UL不明确,因为您使用删除和禁用相同的词语。你应该只使用一个词。

© www.soinside.com 2019 - 2024. All rights reserved.