我正在尝试领域驱动设计和事件溯源。我打算使用(用 C# 开发)NServiceBus、JOliver 的 EventStore 和 NES 来绑定它们。我已经拥有适用于一个简单案例的基础架构(一个仅包含值对象的聚合根)。
我正在阅读 Evans 蓝皮书,并且正在尝试开发一个简单的域模型,其中的示例取自我的工作领域(HVAC 维护公司的 ERP 和 CRM)。
我正在建模一个简单的子域,即 HVAC 机器和它们之间的关系。机器有多种类型,例如熔炉、燃烧器、空调、压缩机、通用组件。每台机器可以有多个子机器。所有机器类型都有一些共同的数据和一些共同的行为。但是每种类型都有额外的数据和特定的行为,例如,您只能将 Burner 对象添加到 Furnace。
我分析的第一个结果是每台机器都应该是一个聚合根(继承自 NES 中的 AggregateBase),因为它必须能够保存对特定机器的引用(例如,用于插入涉及单台机器的维修记录、故障记录、等),并且还可以减少大型机器树中的并发问题。
因此,我的假设如下:
public class Machine : AggregateBase
{
public DateTime InstallationDate { get; private set; }
public Guid ManufacturerId { get; private set; }
public Guid ModelId { get; private set; }
}
public class Furnace : Machine
{
public List<Burner> burners { get; private set; }
// other furnace properties
public void AddBurner(Burner burner)
{
// perform validation
this.Apply<BurnerAdded>(x=> x.burnerAdded = burner);
}
public void Handle(BurnerAdded @event)
{
this.burners.Add(@event.burnerAdded);
}
}
public class Burner : Machine
{
// burner specific properties/methods
}
但我有一些疑问:
这是代表我的域的正确方法吗?我读到不鼓励类继承,但这在我看来是使用它的完美案例(燃烧器是机器,炉子也是)。我将仅限于一级继承。
是否可以使用 Event Sourcing 实现类继承?特别是建议的技术堆栈(nServiceBus、EventStore、NES)?
我应该如何执行添加子机器(例如燃烧器到炉子)?这个操作可以分为两种:
- 将新的 Burner 添加到 Burner 存储库。
- 将 Burner 的引用添加到父 Furnace 的 burners 列表但是这两个操作全局修改了两个聚合根,因此该操作应该在两个单独的 commandhandlers/transactions 中执行...但是第二个取决于第一个...是这是一些建模错误的证据吗?我可以将 nServicebusMessages 批处理在一起以在单个事务中执行操作,但我读到这不好......
如果我让子机器引用父机器,则父机器会丢失子机器列表(验证所需的),我无法查询事件源存储库以获取除 Guid 之外的其他属性。
提前感谢您对讨论的任何贡献,