如何在存储库中的域模型上设置私有字段

问题描述 投票:0回答:3

我目前正在使用使用贫血域模型的代码库,并且我正在尝试将更多逻辑移至域模型中,以实现域模型和域驱动设计,但我正在努力解决以下问题。

我有一个名为 Job 的域模型,如下所示,

public class Job
{
   private DateTime _someOtherDate;
   private DateTime _lastUpdated;

   // this may be called from many different services
   public void SetLastUpdated()
   {
     _lastUpdated = DateTime.UtcNow;
   }
}

在处理作业期间的某个时间点,我想将作业的上次更新日期设置为该特定时间点。为此,我为其创建了一个公共设置器,如您在上面看到的。

当我从存储库中的数据库中撤回作业时,会出现问题,因为我现在没有该字段的公共设置器,因为我已将其限制为

SetLastUpdated()

有人可以建议我如何允许在检索作业时在存储库实现中设置此属性,而不是从限制调用的服务中设置此属性。


更新1)

我已经更新了问题,因为使用开始日期是一个坏例子。

更新2)

从给出的答案中,我可以看到完成此操作的唯一方法是不在存储库中使用AutoMapper,在Job类上添加一个构造函数来设置_lastUpdated,并在构造要返回的Job时使用它在存储库的作业检索方法中。

c# asp.net domain-driven-design
3个回答
3
投票

选项1

假设您的存储库有两种方法:

SetLastUpdated()

您可以为 
public IEnumerable<Job> ReadAll() { ... } public int CreateJob(Job job) { ... }

类提供两个构造函数,一个接受

Job
,另一个则不接受。

DateTime

这并不能阻止服务调用“错误”的构造函数,但至少它向调用者传达了在没有 
public class Job { public Job(DateTime startDate) { this.StartDate = startDate; } public Job() : this(DateTime.UtcNow) { } public DateTime StartDate { get; private set; } }

的情况下调用它的选项。


选项2

与两个不同的

startDate

课程一起工作。


您的存储库可能看起来像这样:

Job

public IEnumerable<Job> ReadAll() { ... }
public int CreateJob(NewJob newJob) { ... }

类可能看起来像:


NewJob

这可以更好地传达意图,因为存储库的 
public class NewJob { public NewJob() { this.StartDate = DateTime.UtcNow; } public DateTime StartDate { get; private set; } }

方法仅接受

Create
的实例,因此模型的用户将被迫创建
NewJob
而不是
NewJob

选项3

忽略存储库的

Job

方法中的

StartDate
,并始终在方法内将其设置为
Create
。或者甚至在数据库中创建一个
DateTime.UtcNow
触发器来设置它。
    


1
投票
总是

将从构造函数开始。 一般来说,这是 ORM 专门设计用来执行的工作类型,但是它也可以利用任何现有的 DTO,这些 DTO 已通过使用

备忘录模式

映射到域对象: Insert

回复:
public Job() { _lastUpdated = DateTime.UtcNow; // ... } public Job(JobData data) { _lastUpdated = data.LastUpdated; //... }

- 自从我使用它以来已经有一段时间了,但是应该可以

您可以指示它在配置中使用反射来访问字段
    

一种常见的方法是为此使用构造函数

1
投票
AutoMapper

您必须以一种或另一种方式公开此方法/属性。如果存储库可以设置它,您可以从其他位置设置它。如果你试图在这方面变得聪明(你可以,例如通过使用接口),你就会陷入过度设计的风险。
    

© www.soinside.com 2019 - 2024. All rights reserved.