我有具有编辑器和一个项目的概念的域模型。

这是编辑器拥有一批项目,和项目不仅具有编辑所有者,而且一些编辑器构件。因此,编辑器还具有许多的“结合”的项目。

我正在一个DDD的方法来模拟这种并使用持久性存储库的图案。不过,我不神交模式不够好,还没有决定我应该怎么做。

我工作的假设是编辑器和项目是潜在在同一集合,根是编辑器。因此,我可以得到一个编辑器,然后枚举其项目,可以从那里列举的项目构件编辑。

不过,如果我只能从我的代码库中获取编辑器,不意味着我必须加载从库中的所有项目,当我拥有他们的编辑器?和,如果我想延迟加载的构件编辑,项目需要到仓库的参考,以及?

可选地,如果我分裂骨料和具有编辑存储库和一个项目库,应该怎么处理跨越两个事务时,当新的项目被添加到编辑诸如?例如:

Editor e = new Editor("Editor Name");
editorRepository.Add(e);

Project p = e.CreateProject("Project Name");
projectRepository.Add(p);    // These two lines
editorRepository.Save(e);    // should be atomic

我是否曲解Repository模式的意图是什么?

有帮助吗?

解决方案

  

我是否曲解Repository模式的意图是什么?

我会说“是啊”,但要知道,我和每一个我已经问了同样的事情,出于同样的原因... “你不是想第四维,马蒂工作人”

让我们把它简化一点,与建设者,而不是坚持先创建方法:

Editor e = new Editor("Editor Name");
e = editorRepository.Add(e);

Project p = new Project("Project Name", e);
p = projectRepository.Add(p);

在下面,您的项目库总是存储有效所有者(p.EditorId)进入,因为它是创建的项目数据,并且按照自己的重新填充编辑的项目,它会在那里。这就是为什么它是一个很好的做法,把所有必需的属性到构造函数。如果你不希望传递整个对象,只是e.Id就行了。

  

和,如果我想延迟加载的构件编辑,项目需要到仓库的参考,以及?

现在,至于如何重新填充按需编辑的项目,你有一对夫妇的取决于你打算什么选择。直说库您希望:

IEnumerable<Project> list = projectRepository.GetAllProjects()
                                .Where(x => x.editorId == e.Id);

但把它放在哪里?内部没有项目,或编辑器,你说得对,否则他们将不得不以访问存储库,这就是没有好。上面的代码是松耦合的,但不能重复使用它自己。你刚刚达到Repository模式的限制。

接下来是应用程序的适配器层,用储存库(StaticServiceWrapper)的共享源和任一某种EditorAdapter对象(或集料或任何你想要打电话给他们)或现在你可以在扩展方法混合,可以跟任何流利所有必要的信息库。我没有做它到底这种方式在生产系统中,但向你展示一个简明的例子:

public static class Aggregators
{
    // one to one, easy
    public static Editor GetOwner(this Project p)
    {
        return StaticServiceWrapper.editorRep.GetEditorById(p.editorId);
    }

    // one to many, medium
    public static IEnumerable<Project> GetProjects(this Editor e) 
    { 
        return StaticServiceWrapper.projectRep.GetAllProjects()
                .Where(x => x.editorId == e.Id);
    }

    // many to many, harder
    public static IEnumerable<Editor> GetMembers(this Project p)
    {
        var list = StaticServiceWrapper.projectMemberMap.GetAllMemberMaps()
                        .Where(x => x.projectId == p.projectId);

        foreach ( var item in list )
            yield return StaticServiceWrapper.editorRep.GetEditorById(item.editorId);
    }
}

基本上,一旦你GETALL,GetById,添加,更新,删除对象库完成后,你就独自离开了协会和移动上了对象/层层次的乐趣部件,如适配器和缓存和业务逻辑( “哦,我的天!”的)。

其他提示

如何分裂责任成EditorOwner和EditorMember?

不知道您的域名,我想像他们会有不同的责任 - 例如,EditorOwner可能是相当丰富(且可能是聚合根),但该项目可能只需要知道一个有限的数量成员,因此,该EditorMember对象可以是相当轻。

这些域对象还可以涉及用户,但是这将是在另一个上下文中。

这是否帮助的东西,或者只是让问题更加复杂?

这取决于您的应用程序的需要。如果这是一个大问题,以加载所有的项目对于给定的编辑器,然后尝试类似的虚拟代理

关于延迟加载项目的成员编辑,如果你使用虚拟替身,我没有看到注射代理与EditorRepository一个问题,因为我不考虑代理是域的一部分。

如果你分手了总结,你可以调查股,作为一个解决原子。这个问题,虽然不是唯一的DDD和我敢肯定,有对交易行为的其他解决方案。

在这里,你有2个不同的关系,一个是所有权和一个入会。

在所有权关系是一个简单的一对多(一个所有者为每个项目)。隶属关系是多对多(按项目,许多项目由编辑多编辑)。

您可以提供关于项目类业主的财产,并在ProjectRepository获得通过特定的编辑器所拥有的所有项目的方法。

有关的一对多的关系,提供关于ProjectRepository工程项目的类成员属性,和一个方法来获得含有指定编辑器作为成员的所有项目。

这似乎也编辑和项目单位,我可能会分裂的总和,但也许这些条款在您的上下文中的具体含义,使其子实体聚集的。

scroll top