因此,我有一个aggregate(Project),其中包含一组实体(ProjectVariables)。变量上没有ID,因为它们在Project Aggregate Root之外没有身份。
public class Project
{
public Guid Id { get; set; }
public string Name { get; set; }
public List<ProjectVariable> ProjectVariables { get; set; }
}
public class ProjectVariable
{
public string Key { get; set; }
public string Value { get; set; }
public List<string> Scopes { get; set; }
}
项目的用户界面是Angular Web应用程序。用户访问项目的详细信息,并可以添加/删除/编辑项目变量。他可以更改名字。直到用户单击“保存”,并且Web应用程序将一些json发布到后端,然后将其向下传递到域,才对数据库持久化。
根据DDD,在Aggregate根上使用小的,简洁的方法对其进行原子更改是正确的做法。此域中的示例可以是Project.AddProjectVariable(projectVariable)方法。
为了保持这种做法,这意味着前端应用程序需要跟踪更改并提交如下内容:
public class SaveProjectCommand
{
public string NewName { get; set; }
public List<ProjectVariable> AddedProjectVariables { get; set; }
public List<ProjectVariable> RemovedProjectVariables { get; set; }
public List<ProjectVariable> EditedProjectVariables { get; set; }
}
我想也可以发布现在编辑的项目,从存储库中检索原始项目,然后将它们进行比较,但这似乎有点荒谬。
该对象将转换为服务层方法,该方法将在Aggregate根上调用方法以实现预期的行为。
所以,这就是我的问题了...
答案 0 :(得分:0)
按照DDD的规定,小巧,简洁 在聚合根上进行原子更改的方法。
我不会那样说。这些方法应尽可能反映具有域含义并与普遍存在的语言中的动词或名词相对应的衔接操作。但是结果发生的状态转换不一定很小,它们可以改变大量的汇总数据。
我同意这并不总是可行的。有时,您只想逐字段更改某些实体。如果发生的太多,也许是时候考虑从富域模型方法转换为CRUD了。
ProjectVariables没有ID。它们是瞬时对象。
因此它们可能是Value Objects而不是实体。
通常,您不修改值对象,而是替换它们(尤其是如果它们是不可变的)。 Project.ReplaceProjectVariables(List)
或其他等效选项可能是您最好的选择。我不认为这太过失落。这里的纯CRUD意味着您在Variables
属性上只有一个setter,甚至不允许创建方法并根据需要命名它。