C# DDD。实体或服务上的方法?

C# DDD。实体或服务上的方法?,c#,domain-driven-design,C#,Domain Driven Design,我在开发新系统时尝试使用DDD。在这个系统中,我有位置,我需要根据您所属的广告组授予访问位置的权限。我还需要从广告组列表中获取允许的位置列表 我得出以下结论: interface IPlaceRepository { Places[] GetPlacesForGroups(AdGroup[] adGroups); } class AdGroup() { string Name { get; private set; } } class Place { string Name {

我在开发新系统时尝试使用DDD。在这个系统中,我有位置,我需要根据您所属的广告组授予访问位置的权限。我还需要从广告组列表中获取允许的位置列表

我得出以下结论:

interface IPlaceRepository
{
  Places[] GetPlacesForGroups(AdGroup[] adGroups);
}

class AdGroup()
{
  string Name { get; private set; }
}

class Place
{
  string Name { get; private set; }
}
现在我需要添加一个函数来授予组对特定位置的访问权。根据DDD,哪种方法是正确的?我有两个建议。 我假设adgroup可以被视为值对象

  • 添加一个要放置的函数
  • 
    void GiveAccessTo(AdGroup AdGroup){…}
    

    并向IPlaceRepository添加一个函数

      void AddGroupToPlace(Place p, Group g) { ... }
    
    然后,我需要将IPlaceRepository注入适当的位置,以便在GiveAccessTo中使用

  • 另一种可能的方法是创建ISecurityService?我可以在那个服务上想出这样的方法
  • 
    无效位置(ADG组,位置p)
    

    与选项1相同,我需要在IPlaceRepository上实现一个方法,并将存储库注入服务

    DDD的方法是什么?

    (间接回答)

    不确定DDD是否有专门针对您的案例的规则。我将遵循以下步骤:

    • 在纸垫上绘制聚合,注意根聚合(哪个实体包含另一个)
    • 画出你的疑问
    • 列出存储允许项列表的几种方法
    • 请记住您将如何将其存储在面向文档的数据库中或其他位置(这是物化视图可能使事情复杂化的地方)
    • 有几种方法是有效的,返回您的查询并选择最佳方法(内存消耗、速度、需要查询的项目数最少)
    • 将安全性与业务API分开,从您使用的框架中使用授权模式
    • 仅使用白名单(列出所有允许的资源,默认情况下拒绝所有资源)
      • (间接回答)

        不确定DDD是否有专门针对您的案例的规则。我将遵循以下步骤:

        • 在纸垫上绘制聚合,注意根聚合(哪个实体包含另一个)
        • 画出你的疑问
        • 列出存储允许项列表的几种方法
        • 请记住您将如何将其存储在面向文档的数据库中或其他位置(这是物化视图可能使事情复杂化的地方)
        • 有几种方法是有效的,返回您的查询并选择最佳方法(内存消耗、速度、需要查询的项目数最少)
        • 将安全性与业务API分开,从您使用的框架中使用授权模式
        • 仅使用白名单(列出所有允许的资源,默认情况下拒绝所有资源)

        存储库保存完整的聚合,通常不会有
        AddGroupToPlace
        方法

        由于
        ADGroup
        是一个值对象,因此可以使用
        GiveAccessTo
        方法将组添加到
        Place
        聚合中。完成此操作后,使用存储库保存完整的
        Place
        aggregate


        当一个操作跨越多个聚合时,通常使用服务。但这通常可以通过使用事件来避免

        存储库保存完整的聚合,通常不会有
        AddGroupToPlace
        方法

        由于
        ADGroup
        是一个值对象,因此可以使用
        GiveAccessTo
        方法将组添加到
        Place
        聚合中。完成此操作后,使用存储库保存完整的
        Place
        aggregate


        当一个操作跨越多个聚合时,通常使用服务。但这通常可以通过使用事件来避免

        您不需要在存储库中包含
        AddXtoY()
        方法。聚合中的所有实体和值对象在保存时(通常,当您的UnitOfWork刷新到DB时)将自动与其根一起保留。您不需要在存储库中包含
        AddXtoY()
        方法。保存聚合时(通常,当UnitOfWork刷新到DB时),聚合中的所有实体和值对象将自动与其根一起持久化。