C# 了解DDD(服务、聚合、实体、存储库和规范)

C# 了解DDD(服务、聚合、实体、存储库和规范),c#,domain-driven-design,C#,Domain Driven Design,我从DDD开始,并试图在我当前的项目中应用,但你可以假设我有数千个问题 在这里,我提供了一个示例域,这样我就可以提出不同的问题,并作为一个练习,您可以向我解释如何制作东西 我们假设的系统必须控制公司以及每个公司的员工 域名。 公司(身份证、姓名、地址) 员工(身份证、姓名、姓氏、年龄) 一个人只能在一家公司工作,而一家公司可以有许多员工在该公司工作 操作 系统必须允许向公司添加新员工。为此,它将接收公司的id和新员工的姓名、姓氏、年龄。有一些限制需要满足: 公司中不能有其他具有相同姓名、

我从DDD开始,并试图在我当前的项目中应用,但你可以假设我有数千个问题

在这里,我提供了一个示例域,这样我就可以提出不同的问题,并作为一个练习,您可以向我解释如何制作东西


我们假设的系统必须控制公司以及每个公司的员工

域名。
  • 公司(身份证、姓名、地址)
  • 员工(身份证、姓名、姓氏、年龄)
一个人只能在一家公司工作,而一家公司可以有许多员工在该公司工作

操作 系统必须允许向公司添加新员工。为此,它将接收公司的
id
和新员工的
姓名、姓氏、年龄。有一些限制需要满足:

  • 公司中不能有其他具有相同姓名、姓氏和年龄的员工
  • 该员工可以在另一家公司工作

问题 我脑子里乱七八糟:)

要实施我正在考虑的操作:

  • 服务接收所有参数
  • 服务调用
    CompanyRepository->findCompanyById
    检索公司实例
  • 服务使用指定的参数创建Employee的新实例
  • 服务调用
    company->addEmployee
    将员工附加到公司
  • 公司->添加员工中
    检查新员工是否满足条件(规范)
  • 服务调用
    CompanyRepository->save(company)
    将公司保存在员工之外
因为
company+employee
是作为集群(聚合)管理的,所以我将公司视为聚合根

  • 这是一个好的实现吗
  • <> LI>如果我考虑“代码>公司+雇员< /COD>一个集合,按照我所描述的保存群集<代码>公司+ Suffe<代码>的方式,当从库中检索公司实例时,也必须检索所有相关的雇员吗?
  • 尊重规范我很容易理解如何检查,例如,一个员工的姓名是否超过10个字符,但是:如果公司有数千名员工,如何检查该员工是否存在于同一家公司
  • 规范可以调用存储库操作吗?如果是的话,而且将公司+员工视为集群是正确的,那么什么是正确的地方呢
    CustomerRepository->findEmployeeByName(idCompany,nameEmployee)
    或更好地创建特定的
    EmployeeRepository
  • 1. 好与坏只是一种看法。DDD不应该是一个教条,您可以充分利用它和您自己的附加功能来构建良好的软件体系结构

    2. 否,公司可以延迟加载员工(即在检索公司后运行时第一次访问
    Employee
    属性时),也可以实现
    load
    方法,该方法还支持分页以仅加载所需的员工

    3. 您应该在存储库级别(例如
    ICompanyRepository.containsememployee(Employee)
    )实现此功能,并使用底层数据映射器执行此繁重的操作

    此外,我倾向于将规范称为存储库中的前置/后置条件,因为这是确保在所有情况下都能满足它们的唯一方法

    4. 我会避免这样做,但是如果你想确保有很多域规则,你需要在规范中使用它们。顺便说一句,我不会使用存储库,而是使用服务

    正确的位置取决于需求。如果要执行检查以确保存储库中存储的域对象处于有效状态,则如果要从
    ICompanyRepository.Add
    ICompanyRepository.Update
    ,或
    ICompanyRepository.AddOrUpdate
    中调用规范,则没有问题。这里的要点是,您不应该在对象状态存储在存储库中和重试时都验证它们。如果您的规范和代码是可靠的,如果存储库已筛选域对象并已将其存储在基础数据存储中,则可以确保than read操作将获得有效的域对象

    旁注:虽然您不应该基于底层数据存储(关系型、NoSQL、文件系统等)对域进行建模,但您也不应该像教条一样应用DDD。如果底层数据存储提供了一种更好的方法来定义数据约束,我会尝试使用它们,而不是实现复杂的规范,这些规范可能需要访问数据


    您的解决方案应该是最佳软件体系结构和运行时性能的平衡。

    Hi Matias。尊重3我的问题是谁负责给它打电话。是的,这可以在存储库中完成,但是规范调用它还是在服务端就可以了?提前谢谢。我明白你的意思,但这就像说一切都是主观的,根本没有好或坏的设计。对特定领域建模肯定有好的和坏的方法。2.延迟加载通常是一种设计气味,指示不正确的聚合根边界。此外,对象模型应针对命令而不是查询(CQR)进行优化。3.这里要小心,数据随时都可能过时。可以检查,但在插入过程中必须依赖唯一的数据库约束来确保唯一性。您还可以询问
    公司
    AR的边界是否足够大。4.可以在存储库和规范之间进行双重分派。埃文斯的书中讨论了这种技术。但是,不应使用存储库强制实施域不变量。这就是域和聚合根的作用。@plalx是的,你说的有好的和坏的/错误的域设计是对的。我的观点是,OP不应该