|
|
1
2
在调用相关逻辑的顺序上调用removeOrderLine。这不包括对它的持久版本进行更改。 稍后,在存储库上调用一个save/update方法,该方法接收修改后的订单。具体的挑战在于知道域对象中发生了什么变化,其中有几个选项(我确信比我列出的选项还多):
|
|
|
2
1
首先,应该公开接口以获取对聚合根的引用(即order())。使用工厂模式新建聚合根的新实例(即order())。 也就是说,聚合根控件上的方法可以访问其相关对象,而不是本身。另外,不要在聚合根上公开复杂类型(即在示例中声明的lines()IList集合)。这违反了decremeter(sp ck)定律,即不能“点走”到order.lines.add()等方法。 此外,还违反了允许客户端访问对聚合根上的内部对象的引用的规则。聚合根 可以 返回内部对象的引用。只要外部客户端不允许保存对该对象的引用。也就是说,你的“命令行”进入removeline()。不能允许外部客户端控制模型的内部状态(即order()及其orderlines())。因此,您应该期望orderline是一个新的实例,可以据此进行操作。
不要忘记创建order()的新实例的工厂:
您的外部客户机确实有权通过接口直接访问iorderlinesrepository,以获取聚合根中某个值对象的引用。但是,我试图通过强制所有聚合根方法的引用来阻止这种情况。因此,您可以将上面的iorderlinerepository标记为内部的,这样它就不会公开。 实际上,我将所有的根创建聚合到多个工厂中。我不喜欢这样的做法,“一些聚合根将有工厂为复杂的类型,其他将不会”。在整个领域建模过程中遵循相同的逻辑要容易得多。”哦,所以sales()是一个类似于根的聚合order()。肯定也有工厂。” 最后要注意的是,如果有一个组合,即salesOrder(),它使用sales()和order()两个模型,那么您将使用一个服务来创建salesOrder()的实例并对其执行操作,因为sales()或order()聚合根以及它们的存储库或工厂都不拥有对sales的控制权order()实体。 我强烈推荐 this free book 由abel avram和floyd marinescu在域驱动器设计(ddd)上直接回答您的问题,在shrot 100页的大字。以及如何将域实体更多地分离为模块等。 编辑:添加了更多代码 |
|
|
3
1
在解决了这个问题之后,我找到了解决办法。在查看了设计器使用l2sl生成的内容之后,我意识到解决方案是order和orderline之间的双向关联。一个订单有多个订单行,而一个订单行只有一个订单。解决方案是使用双向关联和一个名为deleteonnull的映射属性(您可以用google搜索完整的信息)。最后一件我遗漏的事情是,您的实体类需要注册从l2s实体集中添加和删除事件。在这些处理程序中,必须将订单行上的订单关联设置为空。如果您查看L2S设计器生成的一些代码,可以看到一个这样的示例。 我知道这是一个令人沮丧的问题,但经过几天的努力,我已经让它发挥作用。 |
|
|
4
0
作为后续行动…… 我已经切换到使用nhibernate(而不是链接到sql),但实际上您不需要订单行的repo。如果您只是按顺序从集合中删除医嘱行,那么它将只从数据库中删除医嘱行(假设您已正确完成映射)。 当我与内存存储库交换时,如果您想搜索特定的订单行(不知道订单父项),可以编写一个linq to nhibernate查询,将订单链接到orderlineid=值的订单行。这样,当从数据库和内存中查询时,它就会工作。好吧,给你…… |
|
|
Birdalicious · 带日志的装饰图案 1 年前 |
|
|
Saulo Torres · 依赖注入程序在DDD项目上不起作用 2 年前 |
|
|
yyqwerty · 领域驱动设计与Scala[关闭] 2 年前 |
|
|
Tony Raimo · 域实体是否应该调用存储库? 8 年前 |
|
|
Seb · DDD只读存储库返回“值对象” 8 年前 |