Tan*_*Tan 4 c# domain-driven-design aggregateroot
像这样的 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;
}
}
Run Code Online (Sandbox Code Playgroud)
DDD 主要是关于类及其属性的命名,以便它们准确地表达您的软件应该代表的业务领域的部分。
它实际上并没有规定任何技术实现细节,例如事物如何实例化。关键是类的属性和方法在域中有意义。
从域的角度来看,静态.Create()方法没有意义,但new ..()对构造函数的调用也没有意义。
您可以决定域实体/聚合的构造方法应Class.Create()改为new Class()。
例如,如果您使用的框架/库需要公共无参数默认构造函数(常见于 EntityFramework 和一些序列化库),并且您希望实例化的“标准”方法明确(只能使用所有需要的参数进行调用) ),这是实现这一目标的完全有效的方法。
如果您这样做,您应该为所有实体/聚合执行此操作。它成为一种约定,并将被记录为技术实现细节(就像默认情况下的构造函数一样)。
服务并不是真正用于实例化类(这就是工厂的用途)。
但是,您的代码似乎暗示您还在应用 EventSourcing 或其某些变体。假设您随后也在执行 CQRS,那么您的Create命令将在 CommandHandlers 方法中结束Create。如果需要的话,您可以在其中放置验证逻辑之类的东西。
所以那些 CommandHandlers 已经是你的工厂了,你不需要额外的层。
使用这样的静态实例化方法通常用于实现某种 Fluent API,例如使用 Builder 模式。它为链接调用提供语法糖。
因此,它可能会给其他开发人员/消费者留下调用可以链接的错误印象(在您的示例中不能链接)。
您可能仍然想定义默认的公共构造函数,这样您就可以有一个文档注释来不使用该构造函数,并有一个.Create()应该用作构造函数的文档注释。
考虑到所有这些因素,它仍然比仅使用构造函数更好吗?然后一定要这样做。据我所知,它不会影响“DDD-ness”。
| 归档时间: |
|
| 查看次数: |
3874 次 |
| 最近记录: |