C# DDD:我应该在哪里设置修改日期和修改人?存储库还是应用程序服务?

C# DDD:我应该在哪里设置修改日期和修改人?存储库还是应用程序服务?,c#,domain-driven-design,C#,Domain Driven Design,我应该在哪里设置CreatedDate、CreatedBy、ModifiedDate、ModifiedBy等字段?我是否应该将当前用户上下文传递到存储库并在其中进行设置,或者更好的方法是在应用程序服务中进行设置(但必须在每个API方法中进行设置,而不仅仅是在存储库中的添加/更新)?我更喜欢在存储库中进行设置。在现有的Add/update方法中添加一个名为int operatorId或类似的参数 如果您将代码放在应用程序服务中,您需要始终重复自己的代码。如果忘记设置某些值,则保存更改时会抛出异常(

我应该在哪里设置CreatedDate、CreatedBy、ModifiedDate、ModifiedBy等字段?我是否应该将当前用户上下文传递到存储库并在其中进行设置,或者更好的方法是在应用程序服务中进行设置(但必须在每个API方法中进行设置,而不仅仅是在存储库中的添加/更新)?

我更喜欢在存储库中进行设置。在现有的Add/update方法中添加一个名为
int operatorId
或类似的参数


如果您将代码放在应用程序服务中,您需要始终重复自己的代码。如果忘记设置某些值,则保存更改时会抛出异常(有时甚至更糟,没有异常,只有脏数据)。

我们总是在应用程序服务中设置实体状态。存储库用于保存数据,不应包含任何逻辑。域实体是在应用程序服务中创建/修改的,因此您可以在应用程序服务中设置这些字段。创建/修改日期不应反映实体保存到数据库的时间,而应反映实体实际保存/修改的时间


此外,我们发现我们通常必须将域实体映射到数据层实体,以便与底层数据库技术更加友好。我们经常使用像automapper这样的工具来帮助我们自动化这些映射。实体中的字段在其等效数据实体中不存在会增加不必要的复杂性

这取决于您的域

如果值像
CreatedDate
CreatedBy
。。。用于跟踪或记录,然后我会将它们放在
基础结构
(存储库)中

另一方面,如果这些值出于任何原因属于我的域,那么我会将它们放在域层中

示例:想象一下,在银行转账上下文中,客户只能在提交结算后24小时内取消转账。然后域需要
CreateTransferDate
来满足不变量


另一个选项可以是使用所有域事件并保存所发生事件的历史时间数据的侦听器。

CreatedDate、CreatedBy、ModifiedDate和ModifiedBy通常是没有实际域值的概念,但它们更像是一个技术概念;这就是为什么我通常不在应用程序层或域层设置它们,而是在存储库层设置它们。毕竟,存储库层是一个技术层。在某个领域,我不在乎这种信息。当然,除非它是普遍存在的语言的一部分,但大多数情况下它不是

此外,如果ModifiedDate是域/应用程序的一部分,则必须在每次操作时设置它,这将非常繁琐且容易出错。如果您在存储库中执行此操作,则会更容易,因为每次更新都会执行此操作


所以我想问一个问题:企业关心它吗?

我们从不允许实体处于无效状态。我们通过执行契约式设计检查(适用的前提条件、不变量和后条件)来实现这一点。通过这种方式,您可以确保没有人“忘记”设置值“存储库用于保存数据,它们不应包含任何逻辑”,因此您认为
StudentRepository
有一个名为
GetStudents(int grade)
的方法是不正确的,因为它具有按年级获取学生的逻辑?我假设bstrack的意思是“域业务逻辑”