如果我们有一个有限制的上下文,比如aggregate1发布event1和aggregate2想要对其作出反应的2个聚合,那么我们有1种方法:
event1 > aggregate2响应它,event1发布到消息总线,并让一些单独的进程将其捡起&调用aggregate2方法(S)G 212
无论是在同一个有界的上下文中,如果我们想确保不丢失event1 ( aggregate1之间的应用程序崩溃被保存,而aggregate2是为了响应event1而保存的,例如)我很难找到一个例子,说明什么时候选项1会比选项2更好(超过可能的验证)?
我一定是遗漏了什么,但在我所知的这一点上,这似乎是一个纯粹的理论概念,在我看来,在可靠性和保持正确状态的能力方面,这似乎是一个没有现实世界价值的概念。
当然,发布一条消息并让单独的进程侦听/响应它似乎有点过火了,但是在某个地方没有持久化的域事件有什么实际用途(即使在本地DB中也是如此,在这种情况下,我称之为原始消息总线)?
我遗漏了什么?
发布于 2021-10-12 13:30:38
,在有界的上下文和进程中,什么是领域事件的真实应用?
需求:
可以创建categories.
(类别将具有许多与命名无关的其他属性)。
DDD概念:
类别聚合应该负责它自己的内部不变量,但不能知道其他类别聚合的详细信息。
如何确保当前类别的类别名称是全局唯一的,而不需要类别访问所有其他类别?
答:域事件
DomainEvent
public CategoryRenamed : DomainEvent
{
public Category Category { get; }
internal CategoryRenamed(Category category)
{
this.Category = category;
}
}DomainEventHandler
public CategoryRenamedHandler : IDomainEventHandler<CategoryRenamed>
{
public CategoryRenamedHandler(CategoryRenamed domainEvent)
{
string proposedName = domainEvent.Category.Name;
// query database to ensure that proposedName is not already in use
if (inUse)
throw new Exception($"Name {proposedName} already in use." ;
}
}实体
public abstract class Entity
{
List<DomainEvent> _domainEvents = new List<DomainEvent>();
protected AddDomainEvent(DomainEvent domainEvent)
{
_domainEvents.Add(domainEvent);
}
public List<DomainEvent> DomainEvents => _domainEvents;
}范畴
public class Category : Entity
{
public Guid Id { get; private set; }
public string Name { get; private set; }
public Category(Guid id, string name)
{
Id = id;
SetName(name);
}
public Rename(string name)
{
SetName(name);
}
void SetName(string name)
{
// Local Invariants
if (string.IsNullOrWhitespace(name))
throw new Exception("Invalid name");
Name = name;
// Add a domain event for the infrastructure to process
AddDomainEvent(new CategoryRenamed(this));
}
}命令
public class AddCategoryCommand
{
public Guid Id { get; set; }
public string Name { get; set; }
}CommandHandler
public class CommandHandler : ICommandHandler<AddCategoryCommand>
{
readonly ICategoryRepository _categoryRepository;
public CommandHandler(ICategoryRepository categoryRepository)
{
_categoryRepository = categoryRepository;
}
public void HandleCommand(AndCategoryCommand command)
{
Category newCategory = new(command.Id, command.Name);
// Check for domain events before committing to repository
DomainEventDispatcher.DispatchEvents(newCategory.DomainEvents);
// Dispatcher will find the CategoryRenamed event and send 'in-process'
// to CategoryRenamedHandler
// If name was is in use an error will be thrown by the handler (see above)
_categoryRepository.Add(newCategory);
}
}结局
您的分类聚合已经强制执行了它自己的本地不变量,域命令和domainevent处理基础结构已经被利用,以确保所有类别的名称的唯一性。
https://stackoverflow.com/questions/69533841
复制相似问题