我目前正在使用使用贫血域模型的代码库,并且我正在尝试将更多逻辑移至域模型中,以实现域模型和域驱动设计,但我正在努力解决以下问题。
我有一个名为 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时使用它在存储库的作业检索方法中。
假设您的存储库有两种方法:
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
触发器来设置它。AutoMapper
您必须以一种或另一种方式公开此方法/属性。如果存储库可以设置它,您可以从其他位置设置它。如果你试图在这方面变得聪明(你可以,例如通过使用接口),你就会陷入过度设计的风险。