要禁用与我们通常关联的用户配置文件
User.RemoveProfile(ProfileId)
方法。Profile.Disable()
方法Profile.Disable()
内,我们举起了ProfileDisabled
事件。目前,事件存储在每个实体内。当我们在数据库中持久保存用户时,我们会查看用户下的事件,而不是所有关联的配置文件。因此,我们不会发送个人资料事件而会丢失。
供您参考,这是我们用于调度事件的代码:
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
我猜你有两个实体的聚合:用户和个人资料。而用户就是AR。
在聚合上执行操作时会引发事件,因此您应该将它们与AR一起存储。
在您的情况下,操作是“user.removeProfile(profileId)”,因此AR应该引发事件“ProfileRemovedFromUser”或类似的事情。
注意:您的UL不明确,因为您使用删除和禁用相同的词语。你应该只使用一个词。