gpt4 book ai didi

c# - DDD聚合根有一个创建对象的静态方法是否正确

转载 作者:行者123 更新时间:2023-11-30 14:22:25 24 4
gpt4 key购买 nike

这样的Create方法是否正确。或者我应该在服务中创建用户。这会破坏 DDD 概念吗?

对于这种情况,最佳做法是什么?

注意:我也在使用 DI。

  public class User : HistoryBase, IAggregateRoot
{
private IEnumerable<Role> _roles = new List<Role>();
public string Name { get; protected set; }
public string Lastname { get; protected set; }
public string Email { get; protected set; }
public string Password { get; protected set; }
public string EmployeeNumber { get; protected set; }
public bool Active { get; protected set; }
public int SiteID { get; protected set; }
public IEnumerable<Role> Roles { get { return _roles; } }

public static User Create(string name, string lastname, string email, string password, string employeeNumber, Site site)
{
var user = new User()
{
Name = name,
Lastname = lastname,
Email = email,
Password = password,
EmployeeNumber = employeeNumber,
SiteID = site.ID
};

return user;
}
}

最佳答案

DDD 主要是关于类及其属性的命名,以便它们准确地表达您的软件应该代表的业务领域部分。

它实际上并没有规定任何技术实现细节,例如如何实例化事物。重点是类的属性和方法在领域中具有意义

静态 .Create() 方法从域的角度来看没有任何意义,但对构造函数的 new ..() 调用也没有意义。

您可以决定域实体/聚合的构造方法应为 Class.Create() 而不是 new Class()

这不是“错”

例如,如果您使用的框架/库需要一个公共(public)的无参数默认构造函数(常见于 EntityFramework 和一些序列化库)并且您希望实例化的“标准”方法是明确的(只能用所有需要的参数),这是实现该目标的完全有效的方法。

保持一致

如果你这样做,你应该为你所有的实体/聚合做这件事。它成为一种约定,并将记录为技术实现细节(就像默认情况下构造函数一样)。

使用 CommandHandlers,而不是服务(或工厂)

服务并不是真正用于实例化类(那是工厂的用途)。

但是,您的代码似乎暗示您也在应用 EventSourcing 或其某些变体。假设您随后也在执行 CQRS,您有 Create 命令在您的 CommandHandlers Create 方法中结束。如果需要,您可以在此处放置诸如验证逻辑之类的内容。

所以那些 CommandHandlers 已经是你的工厂了,你不需要额外的层。

最后:

像这样使用静态实例化方法通常是为了实现某种 Fluent API,例如使用 Builder 模式。它为链接调用提供语法糖。

因此它可能会给其他开发人员/消费者一种错误的印象,即调用可以被链接(在您的示例中不能)。

您可能仍然希望定义默认的公共(public)构造函数,这样您就可以在文档注释中不使用那个构造函数,并且在 .Create() 上有一个应该用作构造函数。

考虑到所有这些因素,它是否仍然比仅使用构造函数更好?然后一定要去做。据我所知,它不会影响“DDD-ness”。

关于c# - DDD聚合根有一个创建对象的静态方法是否正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49741901/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com