DDD逻辑和持久性无知

时间:2015-06-03 15:37:05

标签: c# .net orm domain-driven-design persistence

考虑以下情况:

public class Document 
{
  private ISet<User> sharedWith;

  public Document(string name) 
  {
    this.sharedWith = new HashSet<User>();
    this.Name = name;
  }

  public string Name { get; private set; }

  public IEnumerable<User> SharedWith 
  {
    get 
    {      
      return this.sharedWith;
    }
  }

  public void ShareWith(User user) 
  {
    if (this.SharedWith.Contains(user)) 
    {      
      throw new Exception("This document is already shared with that user.");
    }

    this.sharedWith.Add(user);
  }
}
  • Documents可以与User
  • 共享
  • 与用户共享文档时,如果该文档已与该用户共享,则抛出异常。
  • 可以与成千上万的用户共享文档。

显然,这不能很好地扩展,因为需要检查SharedWith是否存在用户,导致ORM将整个集合延迟加载到内存中。我可以在应用程序服务中进行存在检查,但我考虑了这个域逻辑,因此我最有意义的是将它保存在Document类中。

我似乎无法弄清楚DDD应如何做到这一点?如果我无法使用ORM怎么办?怎么做这种东西呢?

我想我应该有文档聚合用户聚合

我查看过各种DDD资源(虽然我还没看过这本书),但我似乎无法找到这个特定场景的答案。

2 个答案:

答案 0 :(得分:2)

这很快就完成了所以它并不完美,但你得到了它的要点:

public class User { public Guid UserId { get; set; } }

public class Document
{
    public string Name { get; private set; }

    private ICollection<User> sharedWith = new List<User>();

    private DateTime? publishedOn;

    public Document(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
        {
            throw new ArgumentException("Name is required");
        }

        this.Name = name;
    }

    public void Publish()
    {
        if (this.publishedOn.HasValue == false)
        {
            this.publishedOn = DateTime.UtcNow;
        }
    }

    public void SharedWith(User user)
    {
        if (this.publishedOn.HasValue == false)
        {
            throw new InvalidOperationException("Document must be published for sharing is allowed.");
        }

        sharedWith.Add(user);
    }
}

public interface IDocumentRepository
{
    Document documentOfId(Guid id);

    bool IsAlreadySharedWith(Guid documentId, Guid userId);
}

public interface IUseRepository
{
    User userOfId(Guid id);
}

public class ShareDocumentService
{
    private readonly IUseRepository userRepository;
    private readonly IDocumentRepository documentRepository;

    public void ShareWith(Guid userId, Guid documentId)
    {
        if (documentRepository.IsAlreadySharedWith(documentId, userId))
            throw new InvalidOperationException("Document has already been shared with user.");

        User user = userRepository.userOfId(userId);

        Document doc = documentRepository.documentOfId(documentId);

        doc.SharedWith(user);
    }
}

答案 1 :(得分:1)

我想如果你是在基于纸张/演员的世界中对此进行建模,那么有人会有编组工作谁可以访问哪些文档,这可能依赖于某种基于纸张的人工制品。要获得对文档的访问权限,您必须填写一份文档申请表,该表可能会通过审批流程。

基于纸张的世界中的这种形式将成为多对多链接实体,成为用户访问安全文档的关键。它会使UserDocumentDocumentRequestForm三个独立的实体。