DDD:为实体及其状态创建存储库

时间:2019-11-10 08:40:13

标签: c# tdd domain-driven-design repository-pattern azure-cosmosdb-sqlapi

我在域中有一个实体,需要跟踪其状态。我为此有一个处理程序。此状态类似于InProgressCompletedDeleted。我使用SQL API CosmosDb来存储该数据。

在CosmosDb内,我为那些创建的实体创建了一个容器,并为其状态创建了另一个容器。因此,在代码内部,我为这两个容器有两个存储库。

internal interface EntityRepository
{
   Task AddAsync(Entity entity);
}

internal interface EntityStatusRepository
{
   Task AddAsync(EntityStatus entityStatus);
}

对于每个存储库,我创建了一项服务

public interface EnityService
{
    Task AddAsync(Entity entity);
}

public interface EntityStatusService
{
   Task AddStatusAsync(EntityStatus entityStatus)
}

这些服务已公开为处理程序的公共接口,而不是存储库。

现在我真的很奇怪

  • 基于DDD并具有一个实体及其状态,我应该创建两个分离的存储库,还是将它们作为一个存储库,因为它们是一个上下文?

  • 我是否需要通过一项服务公开实体及其状态?

我想知道是否有人有建议甚至更好的解决方案?

2 个答案:

答案 0 :(得分:0)

我不是DDD专家-仅通过Implementing DDD来阅读Vernon,但是根据我的经验,您对bounded context有疑问。您的模型EntityEntityStatus可能密切相关。在这种情况下,仅当您自己有需要EntityStatusRepository的地方时,才应创建EntityStatuses。如果您都需要它们,只需使用EntityRepository

答案 1 :(得分:0)

看来EntityStatus应该是Entity的属性,但让我们仔细研究一下逻辑以确保。请注意,这些并不是硬性规定,只是我在做出这些决定时的经验法则。情有可原的情况我取代了这些。

  • EntityStatus应该是聚合根吗?这样做有意义吗 自己与EntityStatus一起使用,与任何事物都没有关系 否则,还是仅引用子对象?如果没有,那就是 不是汇总根。这意味着它要么是支持实体,要么是 一个财产。
  • 如果父实体始终始终具有的一个当前值 EntityStatus,并且状态内无需嵌入任何逻辑, 那么最好将其保留为实体上的属性。
  • 如果EntityStatus需要内置的逻辑,则可能应该 是一个价值对象。例如,如果状态只能从X更改为 在某些情况下为Y,但在其他情况下则为否,或者在某些外部过程中为Y 必须在状态更改时启动,它应该是值对象 其值由实体设置。不过,成为价值对象并不一定意味着它是一个单独的实体。

最后,即使有AR拥有有价值的对象,我还是希望将存储库绑定到“聚合根”。 AR更新应该全部保存或不保存,并且跨存储库扩展数据库单个事务并不理想。如果您使用的是工作单位模式,则AR更新应为单个单位。我尝试过为每个表创建一个单独的存储库,其中AR存储库使用单个表存储库,并且对于所有管道代码而言,它感觉太细粒度了。在处理所有漂浮的事物时,也很容易丢失您要完成的商业想法。最后,尽管没有规则可以支配,但您认为正确的事情也是如此。