我有两个具有一些类似功能的传统企业应用程序。我需要构建一个系统来响应来自这些系统的数据更改事件,处理该数据并通过多种格式的API公开组合结果。我想使用事件源/ DDD风格的架构,但我不确定它是否有意义。鉴于下面的简化模型,我该如何设计系统?
注意 - 编辑以下内容以澄清问题:
两个系统都有根据日期包含不同价格的产品。当价格变化时,每个系统可以发出包含遗留系统的标识符,该系统的主键,日期和新价格的事件PriceChanged。产品ID对于系统是唯一的,但在两个系统之间可能不是唯一的,因此系统ID也将包含在内。
PriceUpdated {
int systemId,
int productId,
Date date,
Float amount
}
在我的新系统的有界上下文中,将有一个服务接收此事件,需要通过systemId,productId和date查找我的聚合,然后发出命令以更新聚合中的相应价格。我的聚合定义为:
class ProductPriceAggregate
{
Guid Id,
int systemId,
int productId,
Date date,
Float amount
Apply(CreateProductPriceCommand e){
Id = e.Id;
systemId = e.systemId;
productId = e.productId;
date = e.date;
RaiseEvent(new ProductPriceCreatedEvent(this))
}
Apply(UpdateProductPriceCommand d){
amount = e.amount;
RaiseEvent(new ProductPriceUpdatedEvent(this));
}
}
如果我使用的是使用GUID存储流的NEventStore,那么每个aggreateId将由GUID表示。我的服务需要使用systemId,productId和date查询GUID以发出具有正确ID的命令。
该服务可能如下所示:
class PriceUpdateService : ISubscribeTo<PriceUpdated>{
Handle<PriceUpdated>(PriceUpdated e)
{
var aggregateId = RetrieveId(e.systemId, e.productId, e.date);
if (aggregateId == null)
Raise(new CreateProductPriceCommand(e))
else
Raise(new UpdateProductPriceCommand(aggregateId, e.amount);
}
RetrieveId(int systemId, int productId, DateTime date)
{
// ???
}
}
问题是查找聚合ID的最佳方法是什么?发布PriceUpdated事件的遗留系统将不知道这个新系统。我可以使用为响应ProductPriceCreatedEvent而更新的读取模型,其中包含足够的信息来查询ID吗?我是否需要另一个汇总谁负责索引ProductPrices?由VoiceOfUnreason作为答案发布,我可以使用可重复的约定来生成systemId,productId和date的ID。这是从DDD角度推荐的选项吗?
答案 0 :(得分:2)
你控制自己的身份证吗?
PriceUpdated {
int systemId,
int productId,
Date date,
Float amount
}
尝试查找aggregateId的另一种方法是计算aggregateId必须是什么。基本思想是,需要从此事件中查找聚合的不同点共享一个封装计算的域服务实例。
签名看起来就像您在问题中写的查询
// Just a query, we aren't changing state anywhere.
var aggregateId = idGenerator.getId(e.systemId, e.productId, e.date);
任何给定的实现都会使用它自己的salt,传递给它的参数,并生成一个哈希,它是在任何地方用来将这个参数组合映射到聚合的公共ID。
当然,您可以通过传入具有不同盐的idGenerator,使用相同的事件数据为不同的聚合生成标识符。
对于您的ID为UUID的特定情况,您可以使用Name-Based UUID。