Domain driven design 我应该如何处理DDD配置?

Domain driven design 我应该如何处理DDD配置?,domain-driven-design,Domain Driven Design,实际上,我正在处理日期范围,每天在某个特定的时间,修改应该被锁定。因此,在这段时间之后,我应该不能为实际的一天添加任务,只为第二天添加任务。这个锁定时间应该存储在配置中,我应该能够在管理设置中更改它 将锁定时间注入任务调度器的正确方法是什么?我应该添加一个配置repo,还是应该通过调度程序的实例化来注入它?配置应该是域的一部分吗?锁定是业务规则的一部分。因此,它应该被视为域服务的一部分。此锁定服务是一个业务功能,给定一组值,它将确定是否允许添加或更新任务 我可能会这样做: public clas

实际上,我正在处理日期范围,每天在某个特定的时间,修改应该被锁定。因此,在这段时间之后,我应该不能为实际的一天添加任务,只为第二天添加任务。这个锁定时间应该存储在配置中,我应该能够在管理设置中更改它


将锁定时间注入任务调度器的正确方法是什么?我应该添加一个配置repo,还是应该通过调度程序的实例化来注入它?配置应该是域的一部分吗?

锁定是业务规则的一部分。因此,它应该被视为域服务的一部分。此锁定服务是一个业务功能,给定一组值,它将确定是否允许添加或更新任务

我可能会这样做:

public class LockdownService: ILockdownService{
     public LockdownService(ILockdownRepo lockDownRepo){
         ...
    }

    public bool isLock(){
         //do logic here
    }

    //replace object with your model representation
    public object GetLockdownTime(){
         ...
    }
}


public class TaskSchedulerService{
     public TaskSchedulerService(IUserRepo userRepo, ILockdownService lockDownSvc, ITaskRepo taskRepo){
             ...
     }

    public void ScheduleTask(userId, label, begin, end) {
            var user = userRepo.GetById(userId)
            var lockdownTime = lockDownSvc.GetLockdownTime()
            //do lockdown logic


            //create task if all business rules are satisfied
            taskRepo.ScheduleTask(user.userId, label, begin, end);
    }       
}
如果锁定服务需要关于任务的信息,那么您还可以将任务repo注入到锁定服务构造函数中


希望这能给你一个想法。

锁定时间的概念应该是域模型的一部分,因为它是一个需要捕获的业务规则

将锁定时间注入任务调度器的正确方法是什么?我应该添加一个配置repo,还是应该通过调度程序的实例化来注入它

您已经考虑过将值传递给构造函数,但也可以将其传递给方法调用本身。例如(摘自对alltej答案的评论):

然后你可以像这样使用它:

// taskSchedulingService.cs (ctor takes in a configRepo and userRepo)

public void ScheduleTask(userId, label, begin, end) {
    var user = userRepo.GetById(userId)
    var lockdownTime = configRepo.GetLockdownTime()
    user.ScheduleTask(label, begin, end, lockdownTime)
}
配置应该是域的一部分吗


很难回答这个问题,这取决于域名。我会默认为“否”,因为它通常不是,但也许你有一个域是关于配置的:)大多数时候,你只是在应用程序启动时从数据库或文件中读取一些值,并使用这些值来创建你的服务/对象。在这种情况下,配置本身不是域的一部分-域只需要这些值,即在您的情况下,域将有一个锁定停机概念,但不必关心它来自何处。

您的域到底是什么?任务调度?最终的一致性是否可以接受(例如,在安排新任务的同时更新锁定时间)?@plalx这是否重要?这只是一个例子。实际上,它很复杂,有点像任务调度,但并不完全如此。它不会产生真正的业务影响,因此,如果在添加新任务时更改了设置,则可以接受新任务。“如果在添加新任务时更改了设置,则可以接受新任务。”要获得正确的模型,了解这一点非常重要。我也想知道这些封锁背后的动机?他们是如何成为业务的一个重要方面的?@plalx我将尝试通过这个任务类比来解释这一点,但我不确定这是否可能。您是一名客户,并且有服务提供商(以下简称SP)可以执行客户添加的任务。每天早上,这些SP都会收到他们每天必须完成的任务列表。之后,他们不会与系统交互,因此他们无法接收当天的新任务。这就是为什么在达到锁定时间后,当天被锁定的原因。请注意,实际问题有些不同,但会导致相同的锁定解决方案。@plalx我不确定,但我认为我有一个技术问题,而不是建模问题。检查alltej答案下的评论!哦,在更改设置时接受添加的任务是可以的,因为设置很少更改,SP每天都在同一时间开始工作…不太可能。实际上,我已经有了类似的东西,但不清楚在哪里注入以及如何使用该域服务。我会做一些类似于
user.scheduleTask(label,begin,end)
——如果我有时间完全重构代码的话——所以理论上应该通过
userRepository.findById(userId)
将其注入域对象。这样行吗?将服务注入域对象感觉很奇怪,但我对DDD很陌生,所以可能没问题。我的主要问题是相同的
用户
实例被身份验证重用。它有一个
User.hasRole(role)
和一个
User.isoowner(owner)
方法。通过安装,当
用户
实例经过身份验证时,存在一种状态,但尚未进行配置,这意味着无法通过实例化将锁定服务注入
用户
。Ofc。这是一个糟糕的设计,但我想安装过程不应该是域的一部分。解决这个问题让我有点不知所措。我添加了一个setter,用于注入锁定服务作为解决方法,但这是一个非常丑陋的黑客行为我不希望这个项目是完美的,但至少在理论上学习如何做得更好会很好。不要将锁定服务注入用户对象。而是创建一个TaskSchedulingService,该服务接受构造函数中的userRepo和lockdownService。@inf3rno更新了答案。如果你有问题请告诉我谢谢!我也想到了类似的事情。也许已经很长的参数列表是我没有选择这个的原因,但我认为你是对的,这是一个正确的解决方案。我会等待,也许有人也有一个构造函数注入的解决方案。
// taskSchedulingService.cs (ctor takes in a configRepo and userRepo)

public void ScheduleTask(userId, label, begin, end) {
    var user = userRepo.GetById(userId)
    var lockdownTime = configRepo.GetLockdownTime()
    user.ScheduleTask(label, begin, end, lockdownTime)
}