Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 领域驱动设计中的存储库和聚合根_C#_Domain Driven Design - Fatal编程技术网

C# 领域驱动设计中的存储库和聚合根

C# 领域驱动设计中的存储库和聚合根,c#,domain-driven-design,C#,Domain Driven Design,我正在构建一个通知系统,在该系统中,我有一些用户可以创建订阅,这些订阅可以定义何时向他们发送通知以及由哪个端点发送通知。我已经确定用户是聚合根用户,并且将为他们提供一个存储库。不过,我对这个概念的理解有点困难。根据我的理解,只应从存储库中提取聚合根 假设我有一个用户 public class User { public ICollection<Subscription> Subscriptions {get; set;} public ICollection<E

我正在构建一个通知系统,在该系统中,我有一些用户可以创建订阅,这些订阅可以定义何时向他们发送通知以及由哪个端点发送通知。我已经确定用户是聚合根用户,并且将为他们提供一个存储库。不过,我对这个概念的理解有点困难。根据我的理解,只应从存储库中提取聚合根

假设我有一个用户

public class User
{
    public ICollection<Subscription> Subscriptions {get; set;}
    public ICollection<Endpoint> Endpoints {get; set;}
}
公共类用户
{
公共ICollection订阅{get;set;}
公共ICollection终结点{get;set;}
}
此用户具有订阅和终结点的集合。这两个都是实体本身,因为它们的内容可以更改,而不会成为不同的对象。例如,这两个实体都可以启用/禁用。它们不能存在于用户上下文之外,因为只有用户才能创建订阅或端点

我的订阅还包含对端点的引用,因为此订阅需要知道在何处交付

public class Subscription
{
    public ICollection<Endpoint> Endpoints {get; set;}
}
公共类订阅
{
公共ICollection终结点{get;set;}
}

因此,正如我将用户定义为聚合根一样,我现在有了一个用于持久化用户的UserRepository。对端点或订阅的任何修改都将在作为聚合根的用户的上下文中完成。这对我来说很有意义。但是,如果我想要检索满足一组条件的订阅列表,该怎么办呢。处理触发通知的系统将接收一个事件,并且需要查询与该事件相关的一组订阅。该事件不是基于用户的,因为多个用户可以拥有对此事件有效的订阅。我会在UserRepository上放置一个返回这些订阅的方法吗?或者我会创建一个SubscriptionRepository?如果我创建SubscriptionRepository,这不意味着订阅也是聚合根吗?如果这个问题的答案是肯定的,那么我的设计是否违反了AggregateRoot的概念,因为用户和订阅都包含对端点实体的引用?

首先,我很困惑为什么在用户和订阅中有端点?您是否可以删除用户中的端点,或者删除没有意义的端点

第二,问问你自己

如果我删除一个用户,我是否总是必须删除他的所有订阅和端点

如果答案是“否”,则用户不是聚合根。根据您的描述,我相信您对聚合根的定义是错误的。 如果你真的有AR,你就永远不需要一个独立的存储库来质疑它的实体。它们只使用AR调用,并在其上下文中进行操作(过滤、更改等)

订阅可以是涉及用户并向其添加订阅的过程的一部分。也许订阅是带有其Enpoints的AR

根据我的理解,只应从存储库中提取聚合根

那不太对。存储库是持久性解决方案前面的抽象。从记录簿中提取的任何状态都应该通过存储库

聚合特定于您修改记录簿的用例——换句话说,当您进行写操作时

如果不打算更改任何内容,则不需要(重新)检查聚合边界内的数据是否一致。视图、报告、分析——这些用例不需要聚合,因为它们不会产生任何需要保存在记录簿中的新状态

(CQR:读与写的要求不同)

关键思想是,存储库中只应保存聚合根


因此,如果您有一个需要跨多个聚合读取
端点状态快照的用例,那么请设计一个文档来记录该需求,并确保存储库不包含save。

我的域中的端点是电话号码、电子邮件地址、,我在用户中有端点,因为用户有电话号码和电子邮件地址。我在订阅中有端点,因为用户将订阅一个发送到其电话号码或电子邮件地址的通知。是的,当我删除一个用户时,所有该用户的端点和订阅也会被删除。没有创建它们的用户,它们就无法存在。我希望检索一个用户及其所有端点和订阅,我希望检索一组与事件匹配的订阅。好的,那么只要我的存储库只允许保存聚合根,我就可以以只读方式检索任何子实体。更改该子级的唯一方法是通过聚合根来修改它,在我的例子中,聚合根是用户。由于存储库只允许保存用户,所以我是安全的。