代码之家  ›  专栏  ›  技术社区  ›  Didier A.

如何检索间接引用上的域对象?(当一个实体具有另一个实体的Id而不是直接引用时)

  •  1
  • Didier A.  · 技术社区  · 12 年前

    沃恩·弗农(Vaughn Vernon)有一系列PDF,建议使用间接引用将相关实体链接在一起。这样,实体A将具有实体B ID的列表,而不是对它们的引用。这避免了性能和可扩展性问题,也让您关注一致性边界。

    我的问题是遍历这种类型的间接引用,以便能够执行域逻辑。

    假设我有组、用户和授权。这三个都是实体,也是它们自己的集合体。它们可以彼此同时修改,因此不是一致性边界的一部分。它们以用户在组中的方式相互关联,并且组对事物进行授权。

    我需要域逻辑来检索用户授权的列表 User.GetAuthorizations(); 但如果觉得更合适的话,我愿意把它搬到其他地方。

    问题是,无论我把这个逻辑放在哪里,我都需要:

    1. 获取用户的组。
    2. 对于每个用户组,获取 给定授权。
    3. 执行这些的合并逻辑 批准
    4. 返回适合用户的授权。

    因此,我应该如何实施 User.GetAuthorization(); 在使用存储库进行数据访问的DDD上下文中?

    我的意思是我想知道如何检索间接引用并在方法中遍历它。

    下面是一个示例:

    public class UserApplicationService
    {
        public IEnumerable<Authorization> GetUserAuthorizations(string userId)
        {
            User user = _userRepo.Find(userId);
            IEnumerable<Group> groups = _groupRepo.FindMany(user.GroupIds);
    
            List<Tuple<Group, List<Authorization>>> groupAuths = new List<Tuple<Group, List<Authorization>>>()
            foreach(Group group in groups)
            {
                List<Authorization> auths =  _authorizationRepo.FindMany(group.AuthorizationIds).ToList();
                Tuple<Group, List<Authorization>> groupAuth = new Tuple<Group, List<Authorization>>(group, auths);
                groupAuths.Add(groupAuth);
            }
    
            return user.GetAuthorizations(groupAuths);
        }
    }
    
    IEnumerable<Authorization> User.GetAuthorizations(List<Tuple<Group, List<Authorization>>> groupAuths)
    {
        // merge logic would be here
    }
    

    在本例中,我在应用程序服务中检索用户的组和所有这些组的授权,并将其传递给 User.GetAuthorizations 方法我觉得这很麻烦,如果关系嵌套得更深,就会变得更麻烦。

    我想知道DDD方法还有什么其他方法?这通常是如何完成的?

    2 回复  |  直到 12 年前
        1
  •  1
  •   Community Mohan Dere    5 年前

    问这个问题已经过去了,我已经加深了我的理解,我自己也有信心回答这个问题。

    我需要域逻辑来检索用户授权的列表。理想情况下,我觉得这个逻辑应该在UserasUser.GetAuthorizations()上;但如果觉得更合适的话,我愿意把它搬到其他地方。

    这就是我问题的全部问题所在,我想 检索 逻辑,我错误地认为它必须属于我的领域。

    在DDD中,您有一个域模型,它试图封装应用程序的普遍语言,但仅用于数据更改。这些实体、值对象和聚合根应该封装事务上下文。

    当你想 收到 信息,你绕过所有这些。直接查询您的数据,并以所需的形式准确获取所需的信息。

    问题是,无论我把这个逻辑放在哪里,我都需要:

    获取用户的组。

    执行这些授权的合并逻辑。

    返回适合用户的授权。

    因此,我应该如何实现User.GetAuthorization();在使用存储库进行数据访问的DDD上下文中?对于每个用户组,获取给定的授权。

    这没有抓住重点。正确的方法是让应用程序服务具有GetAuthorizations方法,如我的示例中所示,但该方法不应使用Repository,也不应使用Aggregate Roots User、Group和Authorization。相反,它应该使用第二个抽象,这是一个用于检索持久性数据的查询层,它返回自己的实体类型,这些实体与查询更匹配。因此GetAuthorizations可以检索AuthorizedUser类型的对象。它将实现合并逻辑作为查询过程的一部分。

        2
  •  0
  •   Arnis Lapsa    12 年前

    首先,确保客户实际上需要用户分组来定义授权规则。如果没有,那么您的方法是一种过度使用,请考虑以静态方式定义授权规则。

    另一种方法是创建UserAuthorization实体,该实体会因“用户组已更改”、“授权已删除”等更改而进行适当的变异。然后,只需询问用户的授权规则列表即可。