使用DDD / Repo / UoW / Serv

时间:2019-07-30 11:27:41

标签: c# asp.net rest domain-driven-design repository-pattern

我正在使用以下服务上班休息服务

  • EntityFramework核心。
  • 存储库模式
  • UnitOfWork。
  • 服务模式。
  • 数据传输对象(Dto)。
  • 数据访问对象(实体/ Dao)

有关项目的简短说明:

  • 大型enterprice Rest API服务。

  • 存储库仅负责CRUD。

  • UnitOfWork包含每个存储库,并通过依赖项注入获取DbContext。

  • 我的Dtos是贫乏的模型,我知道许多人认为这是不好的做法,但是当制作具有上千个实体(每个实体包含数百个列)的Master API时,这实际上是必要的。 因此,我的Dto实际上只是镜像Dao的(虽然不是敏感信息)。

  • 每个实体都有其自己的存储库。

  • 每个实体都有其自己的服务类,该服务类主要使用给定实体的存储库。

  • 每个实体都有其自己的控制器和服务类,每个控制器与给定的服务类进行对话。

  • 服务类仅接受Dto,每个函数从Dto转换为Dao,然后验证实体,如果实体无效,则引发异常。调用适当的存储库功能并使用UnitOfWork提交功能保存更改时。

  • 通过导航属性插入,更新和删除已禁用/不允许。

  • 此数据库位于云中,我所服务的公司仅使用边缘数据库,因此我们创建了一个“ SyncEngine”以将数据从旧数据库同步到新的基于云的数据库(this)

问题来了,我应该在哪里以及如何实施这些活动?

假设我有一个“用户”实体,该实体需要一百个字段,而我在实体内部有一个工厂方法,该方法需要一百个参数的长度,这根本不是最优的,那么该事件将被触发甚至不知道它是否已添加到数据库中?因此,我最终向用户发送了一封电子邮件,但是数据库不可用,因此根本没有创建用户。

我知道在DDD中,您应该设置并聚合并在Entity等内部具有事件,但是即使向DB的写入操作失败,事件也会被触发...并且假设我有一个包含数百个必填字段的模型,在Dao / Entity类中有一个带有一百个参数的工厂方法不合适吗?

先谢谢了。 -真心沮丧的人

2 个答案:

答案 0 :(得分:1)

沮丧的人,

通常,您将要在同一数据库事务中保存所做的更改和事件。这样,您可以确保仅在写入更改时才写入事件。

接下来,您应该考虑仅在写入数据库之后才触发电子邮件警报。考虑一个分布式过程,在该过程中,您将从数据库中拾取新事件并将其发布到队列中。然后,您可以使用不同的流程来处理它们(例如,向用户发送电子邮件)。

通常来说,在没有事务保证的情况下尝试在一个流程中完成所有工作是导致状态不一致的秘诀。将您的工作分解为可以保证的小部分工作,不要害怕将工作分流到队列中,在队列中您可以类似地保证工作是否会完成。

关于您的其他问题,

  • 理想情况下,您应该将Root实体包装在Aggregates中,并在那里保持逻辑
  • 您应该仅具有Root实体的存储库。他们应该加载任何依赖的子实体。子实体不需要独立加载,因此不需要存储库
  • 如果要处理数百个列,是否可以垂直划分这些表和实体并将它们转换为许多根?也就是说,所有列是否都在同一时间/用例中得到更新?从读取的角度来看,拥有这样一个大小的实体效率不高,但是在编写时,如果字段是从不同的用例编写的,则在繁重的编写场景下将成为瓶颈。

希望有帮助。

答案 1 :(得分:1)

对域模型的大多数更改应遵循以下顺序

  1. 确定要写下的内容
  2. 写下来
  3. 向世界介绍您写下的内容

1 happens-before 2。

2 happens-before 3。

尝试同时进行2和3开辟了一个世界,需要解决很多昂贵的问题。所以不要这样做?

适合某些情况的另一种方法是在将更改写入模型时记下事件(在步骤2中),然后使用存储的事件列表来决定广播什么(在步骤3中)。 / p>

请参见Udi Dahan:Reliable Messaging without Distributed Transactions

相关问题