【问题标题】:DDD and C# - Restricting access to child entityDDD 和 C# - 限制对子实体的访问
【发布时间】:2012-05-30 21:04:40
【问题描述】:

我几乎可以肯定我忽略了一些简单的事情,但它没有点击。

我有一个 Person 实体(Person 聚合的根)。我还有一个用于身份验证和授权 (Auth) 的子实体,它具有角色列表和权限列表。

我希望通过根管理对角色和权限的修改,在根上使用 AddAuthRole 等方法。

这相当简单,但是我将如何在不暴露 Auth 实体中的任何类似功能的情况下执行此操作?我不希望消费者使用孩子的参考来尝试添加和删除这些列表。

我有一种感觉,这是一些基本的 OO 概念,我应该为自己不知道而感到羞耻……

【问题讨论】:

  • 我知道你已经接受了答案,但 c# 在 System.Collections.ObjectModel 命名空间下确实有一个 ReadOnlyCollection 类。

标签: c# oop domain-driven-design aggregateroot


【解决方案1】:

限制对聚合成员的访问是 IMO 的惯例,而不是严格的强制执行。我不相信您可以在聚合周围设置“物理”边界,它们过于严格且不必要地复杂。见DDD / Aggregates in .NET

我不太了解您示例中类的设计,但如果身份验证和授权是 Person Aggregate 的成员并且您想保护它们,请不要从外部引用它们。这只是一个基本的 DDD 约定,您团队中的每个程序员都应该关心 - 除了直接指向聚合根的引用之外,没有跨聚合引用。

如果您使用不可变值对象,则对域对象的访问限制和保护的需求也会大大减少。角色和权限通常可以是这样的值对象,允许您将它们暴露给世界,而不会有外部对象摆弄它们的状态和修改它们的风险。因为这就是 Aggregates 的首要用途:将某些实体的所有操作规则收集在一个地方,以防止任何人摆弄这些实体。

【讨论】:

  • 只遵循约定而不是在代码中强制限制字面意思对我也有效
  • 谢谢...将模型转换为代码对我来说是新事物。我认为聚合几乎是一个封装和隐藏成员对象的黑匣子。感谢您的澄清。
  • 我认为仅仅遵循约定需要大量的纪律,对我来说并不是一个令人满意的解决方案。在 Java 中,Aggregates 中的子实体可以轻松地使它们的 setter 包可见性和 getter 公开。因此,Aggregate 包之外的任何人都无法更改子实体状态。在 C# 中使用 internal 关键字仍然需要域层内部的纪律。
【解决方案2】:

如果您通过更严格的界面(IEnumerable)公开您的列表,您将能够控制您的聚合用户如何访问它们。您通过 IEnumerable 公开的列表,结合根目录上的添加/删除方法,应该可以为您提供我所解释的您想要的内容。

【讨论】:

    【解决方案3】:

    公开的方法应该受到保护,所有其他的应该是私有的

    【讨论】:

    • 将方法标记为受保护只会将其“公开”给声明类及其子类。
    猜你喜欢
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 2010-11-23
    • 2021-04-19
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多