使用集合更新DDD聚合

时间:2018-07-20 21:18:36

标签: c# angular rest domain-driven-design

因此,我有一个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根上调用方法以实现预期的行为。

所以,这就是我的问题了...

  1. ProjectVariables没有ID。它们是瞬时对象。如果需要删除它们(从UI跟踪更改中传入),如何确定需要在聚合上删除的对象?同样,他们没有身份证明。我可以将替代ID添加到ProjectVariables实体,但这似乎是错误和肮脏的。
  2. 我的UI中的更改跟踪是否似乎使UI做得太多?
  3. 有替代机制吗?一种想法是每次保存时,都只替换项目聚合根中的所有ProjectVariables。那不是让我添加一个Project.ClearVariables()并使用Project.AddProjectVariable()来替换它们吗? Project.ReplaceProjectVariables(List)似乎非常“ CRUDish”
  4. 我缺少一些关键要素吗?在我看来,DDD原子方法不能很好地与一种模式结合使用,在这种模式下,您可以在提交实体之前对实体进行许多不同的更改。

1 个答案:

答案 0 :(得分:0)

  

按照DDD的规定,小巧,简洁   在聚合根上进行原子更改的方法。

我不会那样说。这些方法应尽可能反映具有域含义并与普遍存在的语言中的动词或名词相对应的衔接操作。但是结果发生的状态转换不一定很小,它们可以改变大量的汇总数据。

我同意这并不总是可行的。有时,您只想逐字段更改某些实体。如果发生的太多,也许是时候考虑从富域模型方法转换为CRUD了。

  

ProjectVariables没有ID。它们是瞬时对象。

因此它们可能是Value Objects而不是实体。

通常,您不修改值对象,而是替换它们(尤其是如果它们是不可变的)。 Project.ReplaceProjectVariables(List)或其他等效选项可能是您最好的选择。我不认为这太过失落。这里的纯CRUD意味着您在Variables属性上只有一个setter,甚至不允许创建方法并根据需要命名它。