3

我有一个关于聚合根的问题,他们应该负责删除子对象还是应该由存储库负责?如果我想通过它的 ID 查询一个文件,我应该在我的存储库中为此创建一个特定的方法吗?

我的聚合根的代码片段:

public class Folder {

   #region Properties

   public Guid Id { get;set; }
   public Name { get;set; }
   public virtual ICollection<File> Files { get;set; }

   #endregion

   #region Methods

   public File AddFile(string type, string title, bool share = false)
   {
     ///
   }

   #endregion
}

文件类:

public class File
{
    #region Properties

    public virtual Folder Folder { get; set; }
    public string Title { get; set; }
    public string Type { get; set; }
    public bool Shared { get; set; }

    #endregion

    #region Constructor

    public File(Folder folder, string type, string title, bool share = false)
    {
        ///
    }

    #endregion
}

谢谢

4

3 回答 3

6

聚合根负责域不变量(参见http://dddcommunity.org/library/vernon_2011/)。

所以答案是肯定的,聚合根应该是唯一可以访问它聚合的对象的对象。这意味着任何其他对象都不应获得对 File 的引用,并且该 File 不应公开任何更改其自身状态的方法。

所有改变子对象状态的方法都应该由聚合根本身公开,因为它必须确保聚合不变量。

至于持久化删除,我通常将域事件建模为 .NET 事件:这些事件在返回实体之前由存储库订阅。因此,在事件处理程序中会发生持久性逻辑(有关详细信息,请参见http://epic.tesio.it/doc/manual/observable_entities.html

于 2013-03-07T09:45:26.853 回答
3

AggregateRoots 应该对其子对象负责。在您的示例中,假设文件夹公开了一个大小属性,该属性由文件大小的总和确定。

long Size{get{return Files.Sum(f => f.Size);}

因此,当您实际删除文件时,文件夹需要知道它。

您现在可能没有 Size 属性 - 但遵循 DDD 的部分目的是,当您需要实现它时,它可以简单而干净地执行。

于 2013-03-13T21:57:35.310 回答
3

这在很大程度上取决于您的上下文。如果文件具有独立于文件夹的自己的生命周期,那么您可以将文件设为实体/AR。但是,这意味着您需要打破文件夹中的实例聚合关系,以便它仅具有对文件的引用。像这样的东西:

public class Folder
{
    public Guid Id { get;set; }
    public string Name { get;set; }

    public List<ContainedFile> Files { get;set; }
}


public class File
{
    public Guid Id { get;set; }

    public string Title { get;set; }
}

public class ContainedFile // or FolderFIle or whatever makes sense in your domain
{
    public Guid FileId { get;set; }
}

尝试将对其他 AR 实例的引用保留在 AR 之外。此外,这种双向关系 ( File.Folder) 不是必需的。这可能表明您正在使用域模型进行导航:) --- 尽量不要这样做。

于 2013-03-07T10:57:40.547 回答